Vorkonfigurationen:
# Load the necessary libraries
library(readxl)
## Warning: Paket 'readxl' wurde unter R Version 4.4.2 erstellt
library(plotly)
## Warning: Paket 'plotly' wurde unter R Version 4.4.2 erstellt
## Lade nötiges Paket: ggplot2
## Warning: Paket 'ggplot2' wurde unter R Version 4.4.2 erstellt
##
## Attache Paket: 'plotly'
## Das folgende Objekt ist maskiert 'package:ggplot2':
##
## last_plot
## Das folgende Objekt ist maskiert 'package:stats':
##
## filter
## Das folgende Objekt ist maskiert 'package:graphics':
##
## layout
library(dplyr)
## Warning: Paket 'dplyr' wurde unter R Version 4.4.2 erstellt
##
## Attache Paket: 'dplyr'
## Die folgenden Objekte sind maskiert von 'package:stats':
##
## filter, lag
## Die folgenden Objekte sind maskiert von 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
library(sf)
## Warning: Paket 'sf' wurde unter R Version 4.4.2 erstellt
## Linking to GEOS 3.12.2, GDAL 3.9.3, PROJ 9.4.1; sf_use_s2() is TRUE
library(xml2)
## Warning: Paket 'xml2' wurde unter R Version 4.4.2 erstellt
library(lubridate)
##
## Attache Paket: 'lubridate'
## Die folgenden Objekte sind maskiert von 'package:base':
##
## date, intersect, setdiff, union
library(treemap)
## Warning: Paket 'treemap' wurde unter R Version 4.4.2 erstellt
library(knitr)
## Warning: Paket 'knitr' wurde unter R Version 4.4.2 erstellt
library(ggiraph)
## Warning: Paket 'ggiraph' wurde unter R Version 4.4.2 erstellt
Für die Datenauswertung werden zwei Datensätze geladen. Zum einen die csv mit dem Namen “Fahrraddiebstahl in Berlin 2023 - 2024.csv”.
# Load the CSV dataset with ISO-8859-1 encoding
fahrraddiebstahl_datensatz <- read.csv("20.1 Stuttgart - Fahrraddiebstahl 2023+2024 Berlin/Fahrraddiebstahl in Berlin 2023 - 2024.csv",
fileEncoding = "ISO-8859-1",
colClasses = c("LOR" = "character")) # als character, um zu vermeiden, dass die 0 verloren geht
Zur besseren Datenbearbeitung wird der Datensatz zudem auch in ein Dataframe geladen.
fahrraddiebstahl_datensatz_df <- data.frame(fahrraddiebstahl_datensatz)
Der Dataframe beinhaltet elf verschiedene Attribute.
str(fahrraddiebstahl_datensatz)
## 'data.frame': 39173 obs. of 11 variables:
## $ ANGELEGT_AM : chr "18.10.2024" "18.10.2024" "18.10.2024" "18.10.2024" ...
## $ TATZEIT_ANFANG_DATUM : chr "17.10.2024" "17.10.2024" "17.10.2024" "16.10.2024" ...
## $ TATZEIT_ANFANG_STUNDE: int 15 9 19 16 7 6 14 19 22 15 ...
## $ TATZEIT_ENDE_DATUM : chr "18.10.2024" "17.10.2024" "18.10.2024" "17.10.2024" ...
## $ TATZEIT_ENDE_STUNDE : int 8 20 8 22 15 16 17 11 9 8 ...
## $ LOR : chr "04300517" "07100204" "06100205" "02400624" ...
## $ SCHADENSHOEHE : int 6185 3400 1388 100 305 1000 1250 1000 399 3300 ...
## $ VERSUCH : chr "Nein" "Nein" "Nein" "Nein" ...
## $ ART_DES_FAHRRADS : chr "Fahrrad" "Herrenfahrrad" "Herrenfahrrad" "Damenfahrrad" ...
## $ DELIKT : chr "Fahrraddiebstahl" "Fahrraddiebstahl" "Fahrraddiebstahl" "Fahrraddiebstahl" ...
## $ ERFASSUNGSGRUND : chr "Sonstiger schwerer Diebstahl von Fahrrädern" "Sonstiger schwerer Diebstahl von Fahrrädern" "Sonstiger schwerer Diebstahl von Fahrrädern" "Sonstiger schwerer Diebstahl von Fahrrädern" ...
ANGELEGT_AM: Datum und Uhrzeit der Vorgangsanlage im Format “TT.MM.JJJJ hh:mm”.
TATZEIT_ANFANG_DATUM: Beginn des Tatzeitraums im Format “TT.MM.JJJJ”.
TATZEIT_ANFANG_STUNDE: Stunde des Beginns des Tatzeitraums im Format “hh”.
TATZEIT_ENDE_DATUM: Ende des Tatzeitraums im Format “TT.MM.JJJJ”.
TATZEIT_ENDE_STUNDE: Stunde des Endes des Tatzeitraums im Format “hh”.
LOR: Kennung des Planungsraums (8-stellig) (vvxxyyzz –> vv=Bezirksnummer, xx=Prognosebereich, yy=Bezirksregion, zz=Planungsraum
SCHADENSHOEHE: Wert des entwendeten Gutes in Euro (Summenangabe). Bei Kellereinbrüchen inkludiert dieser Wert alle gestohlenen Gegenstände, wie Fahrräder und andere Objekte. Keine Angabe bei reinem Sachschaden.
VERSUCH: Gibt an, ob es sich um einen Versuch handelt (Mögliche Werte: “ja”/“nein”).
ART_DES_FAHRRADS: Typ des gestohlenen Fahrrads (z. B. Herrenrad, Damenrad). Bei mehreren Fahrrädern unterschiedlichen Typs wird der Wert “diverse Fahrräder” ausgegeben.
DELIKT: Gruppierung des Delikts (Mögliche Werte: “Fahrraddiebstahl” oder “Keller- und Bodeneinbruch”).
ERFASSUNGSGRUND: Detaillierte Beschreibung des Delikts.
Der Datensatz ermöglicht keine direkte Ermittlung der exakten Anzahl gestohlener Fahrräder. Die im Rahmen der Datenanalyse ermittelten Zahlen zu Diebstählen sind daher nicht gleichbedeutend mit der tatsächlichen Anzahl der gestohlenen Fahrräder.
Der Datensatz enthält einen Zeitraum, der den vermuteten Zeitpunkt eines Fahrraddiebstahls angibt. Dieser Zeitraum wurde so gewählt, dass er maximal 72 Stunden umfasst, wie in der Beschreibung des Datensatzes vermerkt. Dennoch kann mit dem Datensatz grobe Kenntnisse über die Dauer und bevorzugte Zeiten von Diebstählen erarbeitet werden. Diese sollten jedoch aus dem zuvor genannten Grund in der Interpretation mit Vorsicht behandelt werden.
Dieses Kapitel beschreibt die Anzahl der Diebstählen absolut und durchschnittlich (absolute Anzahl/Einwohnerzahl). Dabei verwendet der zweite Teil Geo-Daten (Quelle:“https://daten.odis-berlin.de/de/dataset/lor_bezirksregionen_2021/”) und ordnet die Werte den Bezirken/Bezirksregionen über die LOR zu.
Dieses Unterkapitel beschreibt die absolute Anzahl an Fahrraddiebstählen aus dem Datensatz “Fahrraddiebstahl in Berlin 2023 - 2024”.
anzahl_fälle <- nrow(fahrraddiebstahl_datensatz)
print(paste("Die Anzahl der Vorfälle eines Diebstahls oder eines Diebstahlsversuch beträgt:", anzahl_fälle))
## [1] "Die Anzahl der Vorfälle eines Diebstahls oder eines Diebstahlsversuch beträgt: 39173"
# Tabelle erstellen
tabelle_versuche <- table(fahrraddiebstahl_datensatz['VERSUCH'])
# Tabelle als knitr-Tabelle anzeigen
kable(tabelle_versuche, caption = "Tabelle der Versuche")
| VERSUCH | Freq |
|---|---|
| Ja | 169 |
| Nein | 38996 |
| Unbekannt | 8 |
In den meisten Fällen der gemeldeten Fahrraddiebstähle war der Diebstahl erfolgreich, während nur in 169 Fällen der Versuch scheiterte. Der Unterschied könnte jedoch auch darin liegen, dass die betroffene Person den Diebstahlsversuch nicht bemerkt oder nicht gemeldet hat, da die Fahrräder weiterhin vorhanden waren und kein durch den Versuch verursachter Schaden festgestellt wurde.
Dieses Unterkapitel verknüpft den Datensatz mit den Geo-Daten (Quelle: https://daten.odis-berlin.de/de/dataset/lor_bezirksregionen_2021) und der Datei “LOR-Räume mit Kontextindikatoren.xlsx”. Die kombinierten Daten werden in interaktiven Karten und Balkendiagrammen visualisiert, um eine übersichtliche Darstellung auch bei großen Datensätzen zu gewährleisten. Durch hoverbare Elemente können detaillierte Informationen zu den einzelnen Werten und deren Beschreibungen abgerufen werden, ohne die Gesamtübersicht zu beeinträchtigen.
# Lade die Excel-Datei (ersetze "datei.xlsx" durch deinen Dateipfad)
lor_df <- read_excel("20.1 Stuttgart - Fahrraddiebstahl 2023+2024 Berlin/LOR-Räume mit Kontextindikatoren.xlsx", skip = 6) # Überspringe die ersten 6 Zeilen, da diese nicht bestandteil des Datensatzes sind
## New names:
## • `` -> `...1`
## • `` -> `...2`
## • `42735` -> `42735...3`
## • `42735` -> `42735...4`
## • `42735` -> `42735...5`
## • `42735` -> `42735...6`
## • `42735` -> `42735...7`
## • `42735` -> `42735...8`
## • `42735` -> `42735...9`
## • `42735` -> `42735...10`
## • `42735` -> `42735...11`
## • `42735` -> `42735...12`
## • `` -> `...13`
# Bereite die Spaltennamen auf
colnames(lor_df) <- c("Nummer", "Name", "Einwohner", "Jugendarbeitslosigkeit", "Altersarmut", "Kinder und Jugendliche mit Migrationshintergrund", "Einwohner mit Migrationshintergrund", "Ausländische Transferbezieher", "Einfache Wohnlage (einschl. Lärmbelastung)", "Wohndauer über 10 Jahre", "Ausländerinnen und Ausländer", "Nicht-EU-Ausländerinnen und Nicht-EU-Ausländer")
# Wähle nur die Spalten Nummer und Name aus, da nur diese benötigt werden
lor_df_verkleinert <- lor_df[, c("Nummer", "Name", "Einwohner")]
# Kombinieren der DataFrames basierend auf der LOR-Nummer
fahrraddiebstahl_und_lor_df <- merge(fahrraddiebstahl_datensatz_df, lor_df_verkleinert,
by.x = "LOR", by.y = "Nummer",
all = FALSE)
# Importiere die Berlinkarte (Geo-Daten)
berlin_map <- read_sf("https://tsb-opendata.s3.eu-central-1.amazonaws.com/lor_bezirksregionen_2021/lor_bezirksregionen_2021.geojson")
str(lor_df)
## tibble [574 × 13] (S3: tbl_df/tbl/data.frame)
## $ Nummer : chr [1:574] "Nummer" "01100101" "01100102" "01100103" ...
## $ Name : chr [1:574] "Name" "Stülerstraße" "Großer Tiergarten" "Lützowstraße" ...
## $ Einwohner : chr [1:574] "neue LOR-Ebene" "3114" "1327" "5518" ...
## $ Jugendarbeitslosigkeit : chr [1:574] "neue LOR-Ebene" "0" "0" "2.1571600000000002" ...
## $ Altersarmut : chr [1:574] "neue LOR-Ebene" "8.89527" "2.5125600000000001" "19.47308" ...
## $ Kinder und Jugendliche mit Migrationshintergrund: chr [1:574] "neue LOR-Ebene" "83.018870000000007" "84.302329999999998" "86.194029999999998" ...
## $ Einwohner mit Migrationshintergrund : chr [1:574] "neue LOR-Ebene" "56.101480000000002" "54.860590000000002" "58.861910000000002" ...
## $ Ausländische Transferbezieher : chr [1:574] "neue LOR-Ebene" "8.2373799999999999" "1.91083" "21.77665" ...
## $ Einfache Wohnlage (einschl. Lärmbelastung) : chr [1:574] "neue LOR-Ebene" "0" "1.5825199999999999" "13.537509999999999" ...
## $ Wohndauer über 10 Jahre : chr [1:574] "neue LOR-Ebene" "54.209650000000003" "47.619050000000001" "52.572830000000003" ...
## $ Ausländerinnen und Ausländer : chr [1:574] "neue LOR-Ebene" "38.760440000000003" "38.432549999999999" "38.927149999999997" ...
## $ Nicht-EU-Ausländerinnen und Nicht-EU-Ausländer : chr [1:574] "neue LOR-Ebene" "63.131729999999997" "73.529409999999999" "65.083799999999997" ...
## $ NA : chr [1:574] NA NA NA NA ...
str(berlin_map)
## sf [143 × 6] (S3: sf/tbl_df/tbl/data.frame)
## $ BZR_ID : chr [1:143] "126011" "076012" "084012" "121001" ...
## $ BZR_NAME : chr [1:143] "MV Nord" "Marienfelde Nord" "Rudow" "Ost 1 - Reginhardstraße" ...
## $ BEZ : chr [1:143] "12" "07" "08" "12" ...
## $ STAND : chr [1:143] "01.01.2021" "01.01.2021" "01.01.2021" "01.01.2021" ...
## $ GROESSE_m2: num [1:143] 2046187 4367868 12044489 2311029 5249869 ...
## $ geometry :sfc_MULTIPOLYGON of length 143; first list element: List of 1
## ..$ :List of 1
## .. ..$ : num [1:399, 1:2] 388649 388617 388614 388615 388590 ...
## ..- attr(*, "class")= chr [1:3] "XY" "MULTIPOLYGON" "sfg"
## - attr(*, "sf_column")= chr "geometry"
## - attr(*, "agr")= Factor w/ 3 levels "constant","aggregate",..: NA NA NA NA NA
## ..- attr(*, "names")= chr [1:5] "BZR_ID" "BZR_NAME" "BEZ" "STAND" ...
Bei der Aufbereitung der Daten wurden die Namen der Spalten von Kontext-Indikatoren in verständlichere Bezeichnungen geändert.
lor_df:
Jugendarbeitslosigkeit: Prozentsatz der Arbeitslosen unter 25 Jahren nach SGB II im Vergleich zu allen 15- bis unter 25-Jährigen zum Stichtag 31.12.2016.
Altersarmut: Prozentsatz der Empfänger von Grundsicherung nach SGB XII über der Regelaltersgrenze im Vergleich zu allen Personen über der Regelaltersgrenze am 31.12.2016.
Kinder und Jugendliche mit Migrationshintergrund: Prozentsatz der unter 18-Jährigen mit Migrationshintergrund im Vergleich zu allen unter 18-Jährigen insgesamt am 31.12.2016.
Einwohner mit Migrationshintergrund: Prozentsatz der Einwohner mit Migrationshintergrund im Vergleich zu allen Einwohnern insgesamt am 31.12.2016.
Ausländische Transferbezieher: Prozentsatz der ausländischen Empfänger von Transferleistungen nach SGB II im Vergleich zu allen Ausländern unterhalb der Regelaltersgrenze am 31.12.2016.
Einfache Wohnlage (einschl. Lärmbelastung): Prozentsatz der Einwohner in einfacher Wohnlage (einschließlich Lärmbelastung durch Straßenverkehr) im Vergleich zu allen Einwohnern am 31.12.2016.
Wohndauer über 10 Jahre: Prozentsatz der Einwohner, die mindestens 5 Jahre an ihrer aktuellen Adresse wohnen, im Vergleich zu allen Einwohnern im Alter von 5 Jahren und älter am 31.12.2016.
Ausländerinnen und Ausländer: Prozentsatz der Ausländer im Vergleich zu allen Einwohnern am 31.12.2016.
Nicht-EU-Ausländerinnen und Nicht-EU-Ausländer: Prozentsatz der Nicht-EU-Ausländer im Vergleich zu allen Ausländern am 31.12.2016. ### Präpariere die Karten
berlin_map
BZR_ID: Eine eindeutige ID für jedes Gebiet in Berlin (Charakterfeld).
BZR_NAME: Der Name des Bezirks oder Gebietes in Berlin (Charakterfeld).
BEZ: Die Nummer des Bezirks, der das Gebiet repräsentiert (Charakterfeld).
STAND: Das Standdatum der Daten, meist der 01.01.2021 (Charakterfeld).
GROESSE_m2: Die Fläche des Gebiets in Quadratmetern (Numerisch).
geometry: Geometrische Daten, die das Gebiet in Form von Multipolygonen darstellen (Geodaten).
Die Kombination der Geodaten beschränkt sich auf die Ebenen „Bezirk“ und „Bezirksregion“, da die Planungsräume nicht in der Karte dargestellt sind. Die Aufgabenstellung nennt zudem nur explizit die Untersuchung nach Bezirk und Bezirksregion.
Die Verbindung zwischen den Geodaten und den anderen beiden Datensätzen erfolgt über die „BZR_ID“, die den ersten sechs Ziffern der „LOR“ entspricht. Um die Verknüpfung herzustellen, müssen in den Datensätzen die letzten beiden Ziffern der „LOR“ entfernt werden, sodass diese nur noch die Länge von sechs Ziffern hat. Anschließend werden die Nummern zusammengeführt, sofern sie durch die Operation dieselbe Nummer aufweisen.
Es gibt Bezirksregionen, die denselben Namen tragen, jedoch in unterschiedlichen Bezirken existieren. Um spätere Konflikte zu vermeiden, werden doppelte Einträge herausgefiltert. Dann wird der Name der Bezirksregion so angepasst, dass die zugehörige Bezirksnummer an den Namen angehängt wird, um eine eindeutige Zuordnung zu gewährleisten.
# Bezirksregion
# Datensatz für Bezirksregionen präparieren
lor_anzahl_bezirksregion <- fahrraddiebstahl_datensatz %>%
mutate(LOR = as.character(LOR),
LOR = substr(LOR, 1, 6)) %>% # Extrahiere die ersten 6 Zeichen der LOR
group_by(LOR) %>%
summarise(anzahl_bezirksregion = n(), .groups = "drop")
# Zusammenführen der Fahrraddiebstahldaten mit der Berlin-Karte
berlin_map_bezirksregion <- berlin_map %>%
left_join(lor_anzahl_bezirksregion, by = c("BZR_ID" = "LOR"))
# Doppelte Einträge in BZR_NAME finden und deren IDs extrahieren
duplicates <- berlin_map_bezirksregion %>%
group_by(BZR_NAME) %>%
filter(n() > 1) %>%
ungroup()
# Behebe doppelte Einträge in Bezirksregionen, z.B. gibt es die Heerstraße in mehreren Bezirken
duplicate_ids <- duplicates$BZR_ID
# Für jede ID der doppelten Einträge den Bezirk herausfinden und an den Namen anhängen
berlin_map_bezirksregion$BZR_NAME <- sapply(berlin_map_bezirksregion$BZR_ID, function(id) {
if (id %in% duplicate_ids) {
# Hole den Bezirk (BEZ) für diese ID
bez_value <- berlin_map_bezirksregion$BEZ[berlin_map_bezirksregion$BZR_ID == id][1]
# Den Bezirk an den BZR_NAME anhängen
return(paste0(berlin_map_bezirksregion$BZR_NAME[berlin_map_bezirksregion$BZR_ID == id], "_", bez_value))
} else {
return(berlin_map_bezirksregion$BZR_NAME[berlin_map_bezirksregion$BZR_ID == id]) # Falls keine Duplikate, Name unverändert lassen
}
})
# Bezirk
lor_anzahl_bezirk <- fahrraddiebstahl_datensatz %>%
mutate(LOR = as.character(LOR),
LOR = substr(LOR, 1, 2)) %>% # Extrahiere die ersten 2 Zeichen der LOR (für Bezirke)
group_by(LOR) %>%
summarise(anzahl_bezirk = n(), .groups = "drop")
# Absolute Anzahl der Bezirksregionen pro Bezirk
anzahl_bezirksregionen_pro_bezirk <- berlin_map %>%
group_by(BEZ) %>%
summarise(anzahl_bezirksregionen = n(), .groups = "drop")
berlin_map_bezirk <- anzahl_bezirksregionen_pro_bezirk %>%
left_join(lor_anzahl_bezirk, by = c("BEZ" = "LOR"))
Die nachfolgenden Grafiken zeigen die absoluten Anzahlen der gemeldeten Fahrraddiebstähle in Bezug auf die verschiedenen Bezirksregionen und Bezirken.
# Lade ggiraph
library(ggiraph)
# Erstelle die interaktive Karte
p_reg_ggiraph <- ggplot(data = berlin_map_bezirksregion) +
geom_sf_interactive(aes(
fill = anzahl_bezirksregion, # Füllung basierend auf numerischen Daten
tooltip = paste(
"Bezirksregion:", BZR_NAME, "<br>",
"Fälle:", anzahl_bezirksregion
), # Tooltip-Inhalt
data_id = BZR_NAME # Für interaktive Auswahl (falls benötigt)
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Fälle", na.value = "grey") +
theme_minimal() +
labs(
title = "Absolute Anzahl an Fahrraddiebstähle in Berlin: Bezirksregion",
subtitle = "Anzahl der Fälle pro Bezirksregion",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_reg <- girafe(ggobj = p_reg_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_reg <- girafe_options(
interactive_map_reg,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_reg
Im Rahmen der Datenanalyse werden häufig Karten zur Visualisierung eingesetzt, da sie den Bezug zwischen den Geo-Daten und dem Datensatz anschaulich darstellen. Da Kartengrafiken die Unterschiede in den Werten meist nur durch Farbverläufe anzeigen, werden sie durch ergänzende Diagramme ergänzt, um die Daten noch präziser zu veranschaulichen.
Die Karten verdeutlichen die Wertunterschiede durch Farbtonvariationen, wobei Blau für niedrige Werte und Rot für hohe Werte steht. Dieses Farbkonzept bleibt konsistent und wird in allen folgenden Karten beibehalten, die ebenfalls diese Farbvariation nutzen.
Die Kartengrafik zeigt, dass die Anzahl der gemeldeten Fahrraddiebstähle besonders im Stadtzentrum am höchsten ist, was durch die rötliche Farbgebung in dieser Region verdeutlicht wird. Besonders auffällig sind die Bezirke “Tempelhofer Vorstadt” mit insgesamt 1470 Fällen und “Alexanderplatz” mit 1386 gemeldeten Diebstählen, die in der Grafik eine markante rote Färbung aufweisen. Im Gegensatz dazu haben die Bezirke “Schmöckwitz” mit nur 10 und “Müggelheim” mit 20 Fällen deutlich weniger Diebstähle, die durch einen tiefen Blauton hervorgehoben werden.
# Bezirksregionen nach der Anzahl der Fahrraddiebstähle sortieren
berlin_map_bezirksregion <- berlin_map_bezirksregion %>%
arrange(anzahl_bezirksregion)
# Reihenfolge der Bezirksregionen nach der Anzahl der Fahrraddiebstähle für ggplot anpassen
berlin_map_bezirksregion$BZR_NAME <- factor(berlin_map_bezirksregion$BZR_NAME,
levels = berlin_map_bezirksregion$BZR_NAME[order(berlin_map_bezirksregion$anzahl_bezirksregion)])
# Aufgeteilter Plot Bezirksregion
split_data_bezirksregion <- split(berlin_map_bezirksregion, cut(1:nrow(berlin_map_bezirksregion), breaks = 3, labels = FALSE))
# Bestimme den minimalen und maximalen Wert von anzahl_bezirksregion für den gesamten Datensatz
min_val <- min(berlin_map_bezirksregion$anzahl_bezirksregion, na.rm = TRUE)
max_val <- max(berlin_map_bezirksregion$anzahl_bezirksregion, na.rm = TRUE)
# Aufgeteilter Plot mit interaktiven Diagrammen
interactive_plots_bezirksregion_anzahl <- lapply(1:3, function(i) {
p <- ggplot(split_data_bezirksregion[[i]], aes(
x = BZR_NAME,
y = anzahl_bezirksregion,
fill = anzahl_bezirksregion,
tooltip = paste("Bezirksregion: ", BZR_NAME, "<br>Fälle: ", anzahl_bezirksregion)
)) +
geom_bar_interactive(stat = "identity") +
scale_fill_gradient(low = "blue", high = "red", limits = c(min_val, max_val)) +
labs(
title = paste("Absolute Anzahl der Fahrraddiebstähle je Bezirksregion (Teil", i, ")"),
x = NULL, # Entfernt die Beschriftung der x-Achse
y = "Anzahl der Fälle"
) +
theme_minimal() +
theme(axis.text.x = element_blank(), # Entfernt die x-Achsen-Beschriftung
axis.ticks.x = element_blank()) # Entfernt die x-Achsen-Ticks
# Rückgabe des interaktiven ggplot-Objekts
girafe(ggobj = p)
})
# Ergebnisse anzeigen
interactive_plots_bezirksregion_anzahl[[1]]
interactive_plots_bezirksregion_anzahl[[2]]
interactive_plots_bezirksregion_anzahl[[3]]
Das Diagramm zeigt die gleichen Ergebnisse wie die Karte, jedoch in Form eines Balkendiagramms. Die Balken sind aufsteigend nach der Anzahl der Fälle sortiert, wodurch die Unterschiede zwischen den Regionen deutlich hervortreten. Der Farbverlauf der Karte, der die Werte von Blau (niedrig) bis Rot (hoch) darstellt, wurde auch im Balkendiagramm beibehalten.
# Erstelle die interaktive Bezirkskarte
p_bez_ggiraph <- ggplot(data = berlin_map_bezirk) +
geom_sf_interactive(aes(
fill = anzahl_bezirk, # Füllung basierend auf den Bezirksdaten
tooltip = paste0("Bezirk: ", BEZ, "<br>Fälle: ", anzahl_bezirk), # Tooltip-Inhalt
data_id = BEZ # Interaktive ID für Bezirke
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Fälle", na.value = "grey") +
theme_minimal() +
labs(
title = "Absolute Anzahl an Fahrraddiebstähle in Berlin: Bezirk",
subtitle = "Anzahl der Fälle pro Bezirk",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_bez <- girafe(ggobj = p_bez_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_bez <- girafe_options(
interactive_map_bez,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_bez
# Duplikate in der BEZ-Spalte entfernen und sortieren
berlin_map_bezirk <- berlin_map_bezirk %>%
distinct(BEZ, .keep_all = TRUE) %>%
arrange(anzahl_bezirk)
# Konvertiere die BEZ-Spalte in einen Faktor mit der aufsteigenden Reihenfolge der anzahl_bezirk
berlin_map_bezirk$BEZ <- factor(berlin_map_bezirk$BEZ, levels = berlin_map_bezirk$BEZ)
# Erstelle das Plot mit ggiraph
p <- ggplot(berlin_map_bezirk, aes(x = BEZ, y = anzahl_bezirk, fill = anzahl_bezirk,
tooltip = paste("Bezirk: ", BEZ, "<br>Fälle: ", anzahl_bezirk))) +
geom_bar_interactive(stat = "identity", position = "dodge") +
scale_fill_gradient(low = "blue", high = "red") + # Farbverlauf
scale_x_discrete(labels = berlin_map_bezirk$BEZ) + # Bezirknummer als x-Achsen-Beschriftung
labs(
title = "Absolute Anzahl der Fahrraddiebstähle je Bezirk",
x = "Bezirk",
y = "Anzahl der Fälle"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Dreht die x-Achsen-Beschriftung für bessere Lesbarkeit
# Rückgabe des interaktiven ggplot-Objekts
girafe(ggobj = p)
Die Grafiken zeigen, dass die höchste absolute Anzahl gemeldeter Fälle im Zentrum Berlins liegt. Besonders herausstechend sind Bezirk 1 und Bezirk 2, die die meisten Fälle verzeichnen. Zu diesen Bezirken gehören auch Regionen, die in den vorherigen Ergebnissen Spitzenreiter waren, wie “Tempelhofer Vorstadt” und “Alexanderplatz”. Die niedrigsten Fallzahlen finden sich hingegen in Bezirk 5 und Bezirk 10. Müggelheim, das zuvor als Region mit den wenigsten absoluten Fällen identifiziert wurde, liegt jedoch nicht in einem dieser Bezirke. Dabei ist zu beachten, dass die Bezirke unterschiedlich viele Regionen umfassen, was dazu führt, dass beispielsweise Bezirk 9 nun eine deutlich höhere absolute Fallzahl aufweist.
Da es sich dem Kapitel zuvor lediglich um absolute Anzahlen an gemeldeten Fahrradiebstählen handelte, analysiert dieses Kapitel die durchschnittlichen Fahrraddiebstählen. Dabei berechnet sich der Durchschnitt zu einen aus der absoluten Anzahl dividiert durch die Einwohnerzahl der Region/Bezirk aus der Datei “LOR-Räume mit Kontextindikatoren.xlsx” und zu anderen aus der absoluten Anzahl in einem Bezirk, dividiert durch die Anzahl der Regionen in dem Bezirk.
# absolute Anzahl / Einwohner
# Betriebsregion
# Präpariere den Datensatz
lor_durchschnitt_bezirksregion <- fahrraddiebstahl_und_lor_df %>%
mutate(LOR = as.character(LOR), # Stelle sicher, dass LOR als Zeichenkette behandelt wird
LOR = substr(LOR, 1, 6), # Extrahiere die ersten 6 Zeichen der LOR
Einwohner = as.numeric(Einwohner)) %>% # Konvertiere Einwohner in numerische Werte
group_by(LOR) %>% # Nach den ersten 6 Zeichen der LOR gruppieren
summarise(anzahl_bezirksregion = n(),
Einwohner = sum(Einwohner, na.rm = TRUE), .groups = "drop") %>% # Berechne die Summe der Einwohner pro LOR
mutate(durchschnitt_promille = (anzahl_bezirksregion / Einwohner) * 1000) # Berechne Promille
# Zusammenführen der Fahrraddiebstahldaten mit der Berlin-Karte
berlin_map_durschnitt_bezirksregion <- berlin_map %>%
left_join(lor_durchschnitt_bezirksregion, by = c("BZR_ID" = "LOR"))
# Doppelte Einträge in BZR_NAME finden und deren IDs extrahieren
duplicates <- berlin_map_durschnitt_bezirksregion %>%
group_by(BZR_NAME) %>%
filter(n() > 1) %>%
ungroup()
# Behebe doppelte Einträge in Bezirksregionen, z.B. gibt es die Heerstraße in mehreren Bezirken
duplicate_ids <- duplicates$BZR_ID
# Für jede ID der doppelten Einträge den Bezirk herausfinden und an den Namen anhängen
berlin_map_durschnitt_bezirksregion$BZR_NAME <- sapply(berlin_map_durschnitt_bezirksregion$BZR_ID, function(id) {
if (id %in% duplicate_ids) {
# Hole den Bezirk (BEZ) für diese ID
bez_value <- berlin_map_durschnitt_bezirksregion$BEZ[berlin_map_durschnitt_bezirksregion$BZR_ID == id][1]
# Den Bezirk an den BZR_NAME anhängen
return(paste0(berlin_map_durschnitt_bezirksregion$BZR_NAME[berlin_map_durschnitt_bezirksregion$BZR_ID == id], "_", bez_value))
} else {
return(berlin_map_durschnitt_bezirksregion$BZR_NAME[berlin_map_durschnitt_bezirksregion$BZR_ID == id]) # Falls keine Duplikate, Name unverändert lassen
}
})
# Bezirk
# Präpariere den Datensatz für die Durchschnittsberechnung
lor_durchschnitt_bezirk <- fahrraddiebstahl_und_lor_df %>%
mutate(
LOR = as.character(LOR), # Stelle sicher, dass LOR als Zeichenkette behandelt wird
LOR = substr(LOR, 1, 2), # Extrahiere die ersten 2 Zeichen der LOR
Einwohner = as.numeric(Einwohner) # Stelle sicher, dass Einwohner numerisch ist
) %>%
group_by(LOR) %>% # Gruppiere nach den ersten 2 Zeichen der LOR
summarise(
anzahl_bezirksregion = n(), # Zähle die Anzahl der Bezirksregionen pro LOR
Einwohner = sum(Einwohner, na.rm = TRUE), # Berechne die Summe der Einwohner
.groups = "drop"
) %>%
mutate(
durchschnitt_promille = (anzahl_bezirksregion / Einwohner) * 1000 # Berechne den Promille-Wert
)
# Zusammenführen der Daten mit der Berlin-Karte
# Gruppierung der Karte nach Bezirken und Zusammenführung
berlin_map_durchschnitt_bezirk <- berlin_map %>%
group_by(BEZ) %>%
summarise(geometry = st_union(geometry), .groups = "drop") %>% # Geometrien pro Bezirk vereinen
left_join(lor_durchschnitt_bezirk, by = c("BEZ" = "LOR"))
# Erstelle die interaktive Bezirkskarte mit durchschnittlichen Werten
p_bez_ggiraph <- ggplot(data = berlin_map_bezirk) +
geom_sf_interactive(aes(
fill = round(anzahl_bezirk / anzahl_bezirksregionen, 2), # Durchschnittswerte
tooltip = paste0(
"Bezirk: ", BEZ, "<br>",
"Durchschnittliche Fälle: ", round(anzahl_bezirk / anzahl_bezirksregionen, 2)
), # Tooltip-Inhalt
data_id = BEZ # Interaktive ID für Bezirke
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Durchschnittliche Fälle", na.value = "grey") +
theme_minimal() +
labs(
title = "Durchschnittliche Anzahl an Fahrraddiebstähle in Berlin: Bezirk",
subtitle = "Anzahl der Fälle pro Bezirk / Bezirksregionen",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_bez <- girafe(ggobj = p_bez_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_bez <- girafe_options(
interactive_map_bez,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_bez
Diese Karte zeigt das Verhältnis der absoluten Anzahl der Bezirke zur Anzahl der Regionen innerhalb jedes Bezirks. Die unterschiedlichen Farbtöne verdeutlichen, dass die Analyse aus dem vorherigen Kapitel durch die ungleiche Verteilung der Regionen pro Bezirk verfälscht wurde.
Trotz dieser Anpassung bleiben Bezirk 5 und Bezirk 10 die Bezirke mit den geringsten Vorfällen, während Bezirk 1 und Bezirk 2 die Bezirke mit den meisten Vorfällen bleiben. Besonders deutlich zeigt sich eine Veränderung bei den Bezirken 1, 6, 9 und 12.
# Erstelle die interaktive Karte der Bezirksregionen
p_bezirksregion_ggiraph <- ggplot(data = berlin_map_durschnitt_bezirksregion) +
geom_sf_interactive(aes(
fill = durchschnitt_promille, # Durchschnittswerte in Promille
tooltip = paste0(
"Bezirksregion: ", BZR_NAME,
"<br>Durchschnitt (Promille): ", round(durchschnitt_promille, 2)
), # Tooltip-Inhalt
data_id = BZR_NAME # Interaktive ID für Bezirksregionen
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Fälle", na.value = "grey") +
theme_minimal() +
labs(
title = "Durchschnitt an Fahrraddiebstähle in Berlin: Bezirksregion",
subtitle = "Anzahl der Fälle / Anzahl der Einwohner pro Bezirksregion, in Promille",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_bezirksregion <- girafe(ggobj = p_bezirksregion_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_bezirksregion <- girafe_options(
interactive_map_bezirksregion,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_bezirksregion
# Bezirksregionen nach Durchschnitt in Promille sortieren
berlin_map_durschnitt_bezirksregion <- berlin_map_durschnitt_bezirksregion %>%
arrange(durchschnitt_promille)
# Reihenfolge der Bezirksregionen für ggplot anpassen
berlin_map_durschnitt_bezirksregion$BZR_NAME <- factor(berlin_map_durschnitt_bezirksregion$BZR_NAME,
levels = berlin_map_durschnitt_bezirksregion$BZR_NAME[order(berlin_map_durschnitt_bezirksregion$durchschnitt_promille)])
# Aufgeteilter Plot Bezirksregion
split_data_bezirksregion_durchschnitt <- split(berlin_map_durschnitt_bezirksregion, cut(1:nrow(berlin_map_durschnitt_bezirksregion), breaks = 3, labels = FALSE))
# Bestimme den minimalen und maximalen Wert von 'durchschnitt_promille' für den gesamten Datensatz
min_val <- min(berlin_map_durschnitt_bezirksregion$durchschnitt_promille, na.rm = TRUE)
max_val <- max(berlin_map_durschnitt_bezirksregion$durchschnitt_promille, na.rm = TRUE)
# Interaktive Diagramme mit ggiraph
interactive_plots_bezirksregion_durchschnitt <- lapply(1:3, function(i) {
p <- ggplot(split_data_bezirksregion_durchschnitt[[i]], aes(
x = BZR_NAME,
y = durchschnitt_promille,
fill = durchschnitt_promille,
tooltip = paste0(
"Bezirksregion: ", BZR_NAME,
"<br>Durchschnitt (Promille): ", round(durchschnitt_promille, 4)
)
)) +
geom_bar_interactive(stat = "identity") +
scale_fill_gradient(low = "blue", high = "red", limits = c(min_val, max_val)) + # Farbverlauf über alle Plots hinweg
labs(
title = paste("Durchschnitt in Promille je Bezirksregion (Teil", i, ")"),
x = "Bezirksregion",
y = "Durchschnitt in Promille"
) +
theme_minimal() +
theme(
axis.text.x = element_blank(), # Bezirksnamen unter der X-Achse entfernen
axis.ticks.x = element_blank() # Auch die X-Achsen-Striche entfernen
)
# Rückgabe des interaktiven ggplot-Objekts
girafe(ggobj = p)
})
# Ergebnisse anzeigen
interactive_plots_bezirksregion_durchschnitt[[1]]
interactive_plots_bezirksregion_durchschnitt[[2]]
interactive_plots_bezirksregion_durchschnitt[[3]]
Durch die Berücksichtigung der Einwohnerzahl hat sich die Verteilung der Werte deutlich verändert. Die Stadtmitte weist nun wesentlich geringere Werte auf. Überraschenderweise erreichen “Schmöckwitz” sowie “Malchow, Wartenberg und Falkenberg” die höchsten Werte. Im Vergleich dazu hatten diese Bezirksregionen bei der Analyse mit absoluten Zahlen im Verhältnis zu den anderen geringe Fallzahlen gemeldet.
# Erstelle die interaktive Karte der Bezirke
p_bezirk_ggiraph <- ggplot(data = berlin_map_durchschnitt_bezirk) +
geom_sf_interactive(aes(
fill = durchschnitt_promille, # Durchschnittswerte in Promille
tooltip = paste0(
"Bezirk: ", BEZ,
"<br>Durchschnitt (Promille): ", round(durchschnitt_promille, 2)
), # Tooltip-Inhalt
data_id = BEZ # Interaktive ID für Bezirke
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Fälle", na.value = "grey") +
theme_minimal() +
labs(
title = "Durchschnitt an Fahrraddiebstähle in Berlin: Bezirk",
subtitle = "Anzahl der Fälle / Anzahl der Einwohner pro Bezirk, in Promille",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_bezirk <- girafe(ggobj = p_bezirk_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_bezirk <- girafe_options(
interactive_map_bezirk,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_bezirk
# Duplikate in der BEZ-Spalte entfernen und sortieren
berlin_map_durchschnitt_bezirk <- berlin_map_durchschnitt_bezirk %>%
distinct(BEZ, .keep_all = TRUE) %>%
arrange(durchschnitt_promille)
# Konvertiere die BEZ-Spalte in einen Faktor mit der aufsteigenden Reihenfolge der durchschnitt_promille
berlin_map_durchschnitt_bezirk$BEZ <- factor(berlin_map_durchschnitt_bezirk$BEZ, levels = berlin_map_durchschnitt_bezirk$BEZ)
# Erstelle das Plot mit ggiraph
p <- ggplot(berlin_map_durchschnitt_bezirk, aes(x = BEZ, y = durchschnitt_promille, fill = durchschnitt_promille,
tooltip = paste("Bezirk: ", BEZ, "<br>Durchschnitt (Promille): ", round(durchschnitt_promille, 4)))) +
geom_bar_interactive(stat = "identity", position = "dodge") +
scale_fill_gradient(low = "blue", high = "red") + # Farbverlauf
labs(
title = "Durchschnitt der Fahrraddiebstähle je Bezirk",
x = "Bezirk",
y = "Durchschnitt der Fälle"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Rückgabe des interaktiven ggplot-Objekts
girafe(ggobj = p)
Die Analyse unter Berücksichtigung der Einwohnerzahl zeigt deutliche Verschiebungen in der Risikobewertung der Bezirke: Bezirk 5 und 10 liegen nun an der Spitze, während Bezirk 10 zuvor noch deutlich weiter hinten rangierte. Im Gegensatz dazu sind Bezirk 2 und 1, die vorher führten, nun weiter zurückgefallen.
Mit der Einbeziehung der Einwohnerzahl lässt sich das Risiko eines Fahrraddiebstahls in den Bezirken besser abschätzen. Die Ergebnisse zeigen, dass in den Bezirken 5 und 10 das Risiko mit jeweils 0,14 und 0,15 Promille im Vergleich zu den anderen Bezirken am höchsten ist. Das geringste Risiko weist Bezirk 12 mit 0,11 Promille auf. Dennoch liegen die Durchschnittswerte aller Bezirke dicht beieinander, mit Differenzen von lediglich 0,01 Promille.
Es sollte jedoch bedacht werden, dass weitere Faktoren eine Rolle spielen können, etwa Fahrraddiebstähle durch Personen aus anderen Bezirken, Bezirksregionen oder von außerhalb Berlins.
In diesem Kapitel wurde die Analyse der Fahrraddiebstähle in Berlin im Zeitraum 2023-2024 durchgeführt, wobei der Fokus auf zwei Hauptaspekten lag: der absoluten Anzahl der Diebstähle und deren Verteilung auf die verschiedenen Bezirke sowie Bezirksregionen.
Absolute Anzahl der Diebstähle: Der Datensatz „Fahrraddiebstahl in Berlin 2023-2024“ wurde ausgewertet, um die Gesamtzahl der Vorfälle zu ermitteln. Es zeigte sich, dass insgesamt 39.173 Diebstähle verzeichnet wurden. Bei der Differenzierung nach Art des Vorfalls stellte sich heraus, dass die Mehrheit der Diebstähle erfolgreich war: 38.996 Fälle wurden als erfolgreich gemeldet, während nur 169 Fälle als versuchte Diebstähle klassifiziert wurden.
Verknüpfung mit Geo-Daten (Bezirke und Bezirksregionen): Zur weiteren Analyse wurden Geo-Daten der Berliner Bezirke und Bezirksregionen aus einem GeoJSON-Datensatz importiert. Dabei wurden wichtige Informationen wie die Namen der Bezirke, ihre Flächen sowie deren Geometrien extrahiert und visuell in interaktiven Karten und Balkendiagrammen dargestellt. Diese Darstellung ermöglichte einen klaren Vergleich zwischen den einzelnen Bezirken und Bezirksregionen.
Zusätzlich wurden Durchschnittswerte berechnet, die die Anzahl der Diebstähle pro Bezirk und Bezirksregion in Relation zur Anzahl der Bezirksregionen im Bezirk sowie zur Einwohnerzahl der jeweiligen Bezirke und Bezirksregionen setzten. Diese Berechnungen verdeutlichten, dass eine höhere Einwohnerdichte tendenziell mit einer höheren absoluten Diebstahlrate korreliert. Es zeigte sich jedoch auch, dass die durchschnittliche Diebstahlrate pro Einwohner in weniger dicht besiedelten Gebieten nicht notwendigerweise niedriger ausfiel. Überraschenderweise war die Diebstahlrate in Bezirksregionen mit geringerer Einwohnerzahl und weniger absoluten Diebstählen nach Berücksichtigung der Einwohnerzahl deutlich höher, was eine neue Perspektive der Verteilung der Diebstähle offenbarte.
# Tabelle erstellen
tabelle_fahrrad_art <- table(fahrraddiebstahl_datensatz['ART_DES_FAHRRADS'])
# Tabelle in ein Dataframe umwandeln
tabelle_fahrrad_art_df <- as.data.frame(tabelle_fahrrad_art)
# Spalten umbenennen
colnames(tabelle_fahrrad_art_df) <- c("ART_DES_FAHRRADS", "ANZAHL")
# Sicherstellen, dass ANZAHL numerisch ist
tabelle_fahrrad_art_df$ANZAHL <- as.numeric(tabelle_fahrrad_art_df$ANZAHL)
# Plotly Treemap erstellen
library(plotly)
plot_ly(
tabelle_fahrrad_art_df,
type = "treemap",
labels = tabelle_fahrrad_art_df$ART_DES_FAHRRADS, # Labels
parents = rep("", nrow(tabelle_fahrrad_art_df)), # Keine Hierarchie
values = tabelle_fahrrad_art_df$ANZAHL, # Werte
textinfo = "label+value", # Anzeige von Label und Wert
hoverinfo = "label+value", # Anzeige von Label und Wert beim Hover
marker = list(
colors = tabelle_fahrrad_art_df$ANZAHL,
colorscale = "Greens", # Farbabstufung
line = list(color = "white", width = 0.5)
)
) %>%
layout(
title = "Treemap: Arten von Fahrrädern und Diebstahlanzahl"
)
Die Treemap zeigt, dass der größte Anteil der Fahrraddiebstähle im vorliegenden Datensatz auf Herrenfahrräder entfällt, gefolgt von Damenfahrrädern. Rennräder und Lastenfahrräder wurden deutlich seltener gestohlen.
Ein möglicher Einflussfaktor könnte darin liegen, dass Rennräder und Lastenräder in Berlin insgesamt weniger verbreitet sind. Dies könnte ein interessanter Ansatz für weiterführende Analysen sein.
# Tabelle erstellen
tabelle_delikte <- table(fahrraddiebstahl_datensatz['DELIKT'])
# Tabelle in ein Dataframe umwandeln
tabelle_delikte_df <- as.data.frame(tabelle_delikte)
colnames(tabelle_delikte_df) <- c("Delikt", "Anzahl")
# Prozentwerte berechnen
tabelle_delikte_df <- tabelle_delikte_df %>%
mutate(Prozent = round((Anzahl / sum(Anzahl)) * 100, 1),
Label = paste0(Delikt, ": ", Anzahl, " (", Prozent, "%)"))
# Interaktives Kuchendiagramm mit plotly
kuchendiagramm_delikte <- plot_ly(
tabelle_delikte_df,
labels = ~Delikt,
values = ~Anzahl,
type = 'pie',
textinfo = 'none', # Entfernt Beschriftung auf dem Chart
hoverinfo = 'text', # Zeigt Informationen nur beim Hovern
text = ~Label
)
# Diagramm und Layout gestalten
kuchendiagramm_delikte <- kuchendiagramm_delikte %>% layout(
title = "Interaktives Kuchendiagramm der Delikte",
showlegend = TRUE,
legend = list(
x = 1.05, # Position rechts außerhalb des Charts
y = 0.5, # Vertikal mittig (50% der Höhe)
valign = "middle"
),
margin = list(l = 50, r = 150, t = 50, b = 50), # Platz für die Legende rechts
xaxis = list(showgrid = FALSE, zeroline = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE)
)
# Diagramm anzeigen
kuchendiagramm_delikte
Das Kuchendiagramm zeigt, dass in 94,2 % der gemeldeten Fälle ausschließlich Fahrraddiebstähle verzeichnet wurden. In 5,8 % der Fälle erfolgte der Diebstahl jedoch in Verbindung mit einem Keller- oder Bodeneinbruch.
# Tabelle erstellen
tabelle_erfassungsgrund <- table(fahrraddiebstahl_datensatz['ERFASSUNGSGRUND'])
# Tabelle in ein Dataframe umwandeln
tabelle_erfassungsgrund_df <- as.data.frame(tabelle_erfassungsgrund)
colnames(tabelle_erfassungsgrund_df) <- c("Erfassungsgrund", "Anzahl")
# Prozentwerte berechnen
tabelle_erfassungsgrund_df <- tabelle_erfassungsgrund_df %>%
mutate(Prozent = round((Anzahl / sum(Anzahl)) * 100, 1),
Label = paste0(Erfassungsgrund, ": ", Anzahl, " (", Prozent, "%)"))
# Interaktives Kuchendiagramm mit plotly
kuchendiagramm_erfassungsgrund <- plot_ly(
tabelle_erfassungsgrund_df,
labels = ~Erfassungsgrund,
values = ~Anzahl,
type = 'pie',
textinfo = 'none',
hoverinfo = 'text',
text = ~Label
)
# Diagramm gestalten
kuchendiagramm_erfassungsgrund <- kuchendiagramm_erfassungsgrund %>% layout(
title = "Interaktives Kuchendiagramm der Erfassungsgründe",
showlegend = TRUE,
legend = list(
x = 1.05, # Position rechts außerhalb des Charts
y = 0.5, # Vertikal mittig (50% der Höhe)
valign = "middle"
),
margin = list(l = 50, r = 150, t = 50, b = 50), # Platz für die Legende rechts
xaxis = list(showgrid = FALSE, zeroline = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE)
)
# Diagramm anzeigen
kuchendiagramm_erfassungsgrund
Das Kuchendiagramm zeigt, dass 89,2 % der Delikte als schwere Diebstähle von Fahrrädern eingestuft wurden. 5,8 % entfielen auf schwere Diebstähle von oder aus Kellern und Bodenräumen. 4,8 % der Fälle betrafen einfache Fahrraddiebstähle, während lediglich 0,2 % einfache Diebstähle aus Kellern oder Bodenräumen ausmachten.
Art der Fahrräder:
Die Analyse der Fahrradarten zeigt, dass der größte Anteil der
Fahrraddiebstähle im vorliegenden Datensatz auf Herrenfahrräder
entfällt, gefolgt von Damenfahrrädern. Rennräder und Lastenfahrräder
wurden deutlich seltener gestohlen. Eine Treemap zeigt diese Verteilung
visuell, wobei Herrenfahrräder am häufigsten betroffen sind. Ein
möglicher Einflussfaktor könnte darin liegen, dass Rennräder und
Lastenräder in Berlin insgesamt weniger verbreitet sind, was ein
interessanter Ansatz für weiterführende Analysen darstellt.
Delikte:
Die Analyse der Delikte zeigt, dass in 94,2 % der gemeldeten Fälle
ausschließlich Fahrraddiebstähle verzeichnet wurden, während in 5,8 %
der Fälle der Diebstahl in Verbindung mit einem Keller- oder
Bodeneinbruch stattfand. Dies wurde durch ein interaktives
Kuchendiagramm visualisiert, das die Verteilung der Delikte detailliert
zeigt. Verteilung der Erfassungsgründe:
In Bezug auf den Erfassungsgrund zeigt die Auswertung, dass 89,2 % der
Delikte als schwere Diebstähle von Fahrrädern eingestuft wurden. Weitere
5,8 % entfielen auf schwere Diebstähle von oder aus Kellern und
Bodenräumen. Ein kleinerer Anteil (4,8 %) betraf einfache
Fahrraddiebstähle, während lediglich 0,2 % einfache Diebstähle aus
Kellern oder Bodenräumen ausmachten. Ein interaktives Kuchendiagramm
verdeutlicht diese Verteilung und hebt die unterschiedlichen
Erfassungsgründe hervor.
# Gesamtschadenshöhe und Durchschnitt berechnen
fahrrad_schaden_stats <- aggregate(SCHADENSHOEHE ~ ART_DES_FAHRRADS,
data = fahrraddiebstahl_datensatz,
FUN = function(x) c(Gesamt = sum(x), Durchschnitt = mean(x)))
# Ergebnis als DataFrame umwandeln
fahrrad_schaden_stats_df <- do.call(data.frame, fahrrad_schaden_stats)
# Spalten umbenennen
colnames(fahrrad_schaden_stats_df) <- c("ART_DES_FAHRRADS", "Gesamt", "Durchschnitt")
# Summe und Durchschnitt formatieren (mit Punkten und Währung)
fahrrad_schaden_stats_df$Gesamt <- format(fahrrad_schaden_stats_df$Gesamt, big.mark = ".", decimal.mark = ",")
fahrrad_schaden_stats_df$Gesamt <- paste0(fahrrad_schaden_stats_df$Gesamt, " €")
fahrrad_schaden_stats_df$Durchschnitt <- format(round(fahrrad_schaden_stats_df$Durchschnitt, 2), big.mark = ".", decimal.mark = ",")
fahrrad_schaden_stats_df$Durchschnitt <- paste0(fahrrad_schaden_stats_df$Durchschnitt, " €")
plot_ly(
fahrrad_schaden_stats_df,
type = "treemap",
labels = fahrrad_schaden_stats_df$ART_DES_FAHRRADS, # Labels
parents = rep("", nrow(fahrrad_schaden_stats_df)), # Keine Hierarchie
values = as.numeric(gsub("\\.", "", gsub(" €", "", fahrrad_schaden_stats_df$Gesamt))), # Werte ohne Punkte und Währung
textinfo = "label+text", # Anzeige von Label, Wert und Zusatzinfos
hoverinfo = "label+text", # Anzeige von Label, Wert und Zusatzinfos beim Hover
text = paste0(
"Gesamtschaden: ", fahrrad_schaden_stats_df$Gesamt, "<br>",
"Durchschnittl. Schaden: ", fahrrad_schaden_stats_df$Durchschnitt
), # Zusatzinfos
marker = list(
colors = as.numeric(gsub("\\.", "", gsub(" €", "", fahrrad_schaden_stats_df$Gesamt))),
colorscale = "Blues", # Farbabstufung
line = list(color = "white", width = 0.5)
)
) %>%
layout(
title = "Treemap: Schadenshöhen je Fahrradart"
)
Die dargestellte Treemap gibt einen Überblick über die Gesamtschadenshöhen und durchschnittlichen Schadensbeträge je Fahrradart. Die größte Kategorie ist das Herrenfahrrad, das mit einem Gesamtschaden von 22.029.945 € und einem durchschnittlichen Schaden von 1.244,63 € den größten Anteil einnimmt. Es folgt das Damenfahrrad mit einem Gesamtschaden von 10.216.520 € und einem durchschnittlichen Schaden von 1.007,94 €.
Fahrräder allgemein verursachen Schäden in Höhe von 8.346.700 €, wobei der durchschnittliche Schaden 1.354,76 € beträgt. Kleinere Kategorien wie diverse Fahrräder tragen mit 2.517.623 € Gesamtschaden (durchschnittlich 2.235,01 €) weniger zur Gesamtsumme bei. Weitere Fahrradtypen, wie beispielsweise Mountainbikes, sind ebenfalls enthalten, spielen aber in der Gesamtheit eine geringere Rolle.
Die Größe und Farbe der Flächen in der Treemap reflektieren dabei sowohl die Höhe der Gesamtschäden als auch die relative Bedeutung der einzelnen Kategorien im Vergleich.
# Betriebsregion
lor_schadenshöhe_bezirksregion <- fahrraddiebstahl_datensatz %>%
mutate(LOR = as.character(LOR), # Stelle sicher, dass LOR als Zeichenkette behandelt wird
LOR = substr(LOR, 1, 6)) %>% # Extrahiere die ersten 6 Zeichen der LOR
group_by(LOR) %>% # Nach den ersten 6 Zeichen der LOR gruppieren
summarise(SCHADENSHOEHE_SUMME = sum(SCHADENSHOEHE, na.rm = TRUE), .groups = "drop") # Summiere die Schadenshöhe
# Zusammenführen der Fahrraddiebstahldaten mit der Berlin-Karte
berlin_map_schadenshöhe_bezirksregion <- berlin_map %>%
left_join(lor_schadenshöhe_bezirksregion, by = c("BZR_ID" = "LOR"))
# Bezirk
lor_schadenshöhe_bezirk <- fahrraddiebstahl_datensatz %>%
mutate(LOR = as.character(LOR), # Stelle sicher, dass LOR als Zeichenkette behandelt wird
LOR = substr(LOR, 1, 2)) %>% # Extrahiere die ersten 2 Zeichen der LOR
group_by(LOR) %>% # Nach den ersten 2 Zeichen der LOR gruppieren
summarise(SCHADENSHOEHE_SUMME = sum(SCHADENSHOEHE, na.rm = TRUE), .groups = "drop") # Summiere die Schadenshöhe
# Geometrien pro Bezirk vereinigen und mit Schadenshöhen verbinden
berlin_map_schadenshöhe_bezirk <- berlin_map %>%
group_by(BEZ) %>%
summarise(geometry = st_union(geometry), .groups = "drop") %>% # Geometrien pro Bezirk vereinen
left_join(lor_schadenshöhe_bezirk, by = c("BEZ" = "LOR")) # Verknüpfen der Bezirks-IDs
# Betriebsregion
# Präpariere den Datensatz
lor_schadenshöhe_durchschnitt_bezirksregion <- fahrraddiebstahl_und_lor_df %>%
mutate(LOR = as.character(LOR), # Stelle sicher, dass LOR als Zeichenkette behandelt wird
LOR = substr(LOR, 1, 6), # Extrahiere die ersten 6 Zeichen der LOR
Einwohner = as.numeric(Einwohner)) %>% # Konvertiere Einwohner in numerische Werte
group_by(LOR) %>% # Nach den ersten 6 Zeichen der LOR gruppieren
summarise(SCHADENSHOEHE_SUMME = sum(SCHADENSHOEHE, na.rm = TRUE),
Einwohner = sum(Einwohner, na.rm = TRUE), .groups = "drop") %>% # Berechne die Summe der Einwohner pro LOR
mutate(SCHADENSHOEHE_DURCHSCHNITT = (SCHADENSHOEHE_SUMME / Einwohner) * 1000) # Berechne Promille
# Zusammenführen der Fahrraddiebstahldaten mit der Berlin-Karte
berlin_map_schadenshöhe_durschnitt_bezirksregion <- berlin_map %>%
left_join(lor_schadenshöhe_durchschnitt_bezirksregion, by = c("BZR_ID" = "LOR"))
# Bezirk
# Präpariere den Datensatz
lor_schadenshöhe_durchschnitt_bezirk <- fahrraddiebstahl_und_lor_df %>%
mutate(LOR = as.character(LOR), # Stelle sicher, dass LOR als Zeichenkette behandelt wird
LOR = substr(LOR, 1, 2), # Extrahiere die ersten 2 Zeichen der LOR
Einwohner = as.numeric(Einwohner)) %>% # Stelle sicher, dass Einwohner numerisch ist
group_by(LOR) %>% # Nach den ersten 2 Zeichen der LOR gruppieren
summarise(SCHADENSHOEHE_SUMME = sum(SCHADENSHOEHE, na.rm = TRUE),
Einwohner = sum(Einwohner, na.rm = TRUE), .groups = "drop") %>% # Berechne die Summe der Einwohner pro LOR
mutate(SCHADENSHOEHE_DURCHSCHNITT = (SCHADENSHOEHE_SUMME / Einwohner) * 1000) # Berechne Promille
# Zusammenführen der Fahrraddiebstahldaten mit der Berlin-Karte
# Zusammenführen der Fahrraddiebstahldaten mit der Berlin-Karte
berlin_map_schadenshöhe_durchschnitt_bezirk <- berlin_map %>%
group_by(BEZ) %>%
summarise(geometry = st_union(geometry), .groups = "drop") %>% # Geometrien pro Bezirk vereinen
left_join(lor_schadenshöhe_durchschnitt_bezirk, by = c("BEZ" = "LOR"))
# Erstelle die interaktive Karte der Bezirksregionen basierend auf der Schadenshöhe
p_schadenshoehe_bezirksregion_ggiraph <- ggplot(data = berlin_map_schadenshöhe_bezirksregion) +
geom_sf_interactive(aes(
fill = SCHADENSHOEHE_SUMME, # Schadenshöhe
tooltip = paste(
"Bezirksregion:", BZR_NAME,
"<br>Schadenshöhe (€):", SCHADENSHOEHE_SUMME
), # Tooltip-Inhalt
data_id = BZR_NAME # Interaktive ID für Bezirksregionen
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Schadenshöhe (€)", na.value = "grey") +
theme_minimal() +
labs(
title = "Absolute Schadenshöhe bei Fahrraddiebstählen in Berlin: Bezirksregion",
subtitle = "Schadenshöhe in Euro pro Bezirksregion",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_schadenshoehe_bezirksregion <- girafe(ggobj = p_schadenshoehe_bezirksregion_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_schadenshoehe_bezirksregion <- girafe_options(
interactive_map_schadenshoehe_bezirksregion,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_schadenshoehe_bezirksregion
# Erstelle die interaktive Karte der Bezirke basierend auf der Schadenshöhe (in Tausend Euro)
p_schadenshoehe_bezirk_ggiraph <- ggplot(data = berlin_map_schadenshöhe_bezirk) +
geom_sf_interactive(aes(
fill = SCHADENSHOEHE_SUMME / 1000, # Schadenshöhe in Tausend Euro
tooltip = paste(
"Bezirk:", BEZ,
"<br>Schadenshöhe (T€):", round(SCHADENSHOEHE_SUMME / 1000, 1)
), # Tooltip-Inhalt
data_id = BEZ # Interaktive ID für Bezirke
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Schadenshöhe (T€)", na.value = "grey") +
theme_minimal() +
labs(
title = "Absolute Schadenshöhe bei Fahrraddiebstählen in Berlin: Bezirk",
subtitle = "Schadenshöhe in Tausend Euro pro Bezirk",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_schadenshoehe_bezirk <- girafe(ggobj = p_schadenshoehe_bezirk_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_schadenshoehe_bezirk <- girafe_options(
interactive_map_schadenshoehe_bezirk,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_schadenshoehe_bezirk
In dieser Analyse wurde ebenfalls eine Karte verwendet, die die absolute Anzahl der Diebstähle pro Bezirk und Bezirksregion darstellt. Um genauere Rückschlüsse auf die Schadenshöhe zu ziehen, erfolgt anschließend eine detailliertere Untersuchung. Nachdem die Karten betrachtet wurden, die den Durchschnitt der Schadenshöhe im Verhältnis zur Einwohnerzahl zeigen, wird eine tiefere Analyse durchgeführt. Wie bereits in der vorherigen Analyse erkennbar, sind diese Werte besser geeignet, um die Schadenshöhe präziser zu bewerten.
# Erstelle die interaktive Karte der Bezirksregionen basierend auf der durchschnittlichen Schadenshöhe
p_schadenshoehe_durchschnitt_bezirksregion_ggiraph <- ggplot(data = berlin_map_schadenshöhe_durschnitt_bezirksregion) +
geom_sf_interactive(aes(
fill = SCHADENSHOEHE_DURCHSCHNITT, # Durchschnittliche Schadenshöhe
tooltip = paste0(
"Bezirksregion: ", BZR_NAME,
"<br>Durchschnittliche Schadenshöhe: ", scales::comma(round(SCHADENSHOEHE_DURCHSCHNITT, 2)), " €"
), # Tooltip-Inhalt
data_id = BZR_NAME # Interaktive ID für Bezirksregionen
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Durchschnitt (€)", na.value = "grey") +
theme_minimal() +
labs(
title = "Durchschnitt der Schadenshöhe von Fahrraddiebstählen in Berlin: Bezirksregion",
subtitle = "Durchschnitt: Schadenshöhe / Anzahl der Einwohner pro Bezirksregion",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_schadenshoehe_durchschnitt_bezirksregion <- girafe(ggobj = p_schadenshoehe_durchschnitt_bezirksregion_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_schadenshoehe_durchschnitt_bezirksregion <- girafe_options(
interactive_map_schadenshoehe_durchschnitt_bezirksregion,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_schadenshoehe_durchschnitt_bezirksregion
# Erstelle die interaktive Karte der Bezirke basierend auf der durchschnittlichen Schadenshöhe
p_schadenshoehe_durchschnitt_bezirk_ggiraph <- ggplot(data = berlin_map_schadenshöhe_durchschnitt_bezirk) +
geom_sf_interactive(aes(
fill = SCHADENSHOEHE_DURCHSCHNITT, # Durchschnittliche Schadenshöhe
tooltip = paste0(
"Bezirk: ", BEZ,
"<br>Durchschnittliche Schadenshöhe: ", scales::comma(round(SCHADENSHOEHE_DURCHSCHNITT, 2)), " €"
), # Tooltip-Inhalt
data_id = BEZ # Interaktive ID für Bezirke
), color = "black") +
scale_fill_gradient(low = "blue", high = "red", name = "Durchschnitt (€)", na.value = "grey") +
theme_minimal() +
labs(
title = "Durchschnitt der Schadenshöhe von Fahrraddiebstählen in Berlin: Bezirk",
subtitle = "Durchschnitt: Schadenshöhe / Anzahl der Einwohner pro Bezirk",
caption = "Quelle: Fahrraddiebstahl-Datensatz und LOR-Daten"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_schadenshoehe_durchschnitt_bezirk <- girafe(ggobj = p_schadenshoehe_durchschnitt_bezirk_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_schadenshoehe_durchschnitt_bezirk <- girafe_options(
interactive_map_schadenshoehe_durchschnitt_bezirk,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_schadenshoehe_durchschnitt_bezirk
# Duplikate in der BEZ-Spalte entfernen und sortieren
berlin_map_schadenshöhe_durchschnitt_bezirk <- berlin_map_schadenshöhe_durchschnitt_bezirk %>%
distinct(BEZ, .keep_all = TRUE) %>%
arrange(SCHADENSHOEHE_DURCHSCHNITT)
# Konvertiere die BEZ-Spalte in einen Faktor mit der aufsteigenden Reihenfolge der SCHADENSHOEHE_DURCHSCHNITT
berlin_map_schadenshöhe_durchschnitt_bezirk$BEZ <- factor(berlin_map_schadenshöhe_durchschnitt_bezirk$BEZ,
levels = berlin_map_schadenshöhe_durchschnitt_bezirk$BEZ)
# Erstelle das interaktive Plot mit ggiraph
p <- ggplot(berlin_map_schadenshöhe_durchschnitt_bezirk, aes(x = BEZ, y = SCHADENSHOEHE_DURCHSCHNITT,
fill = SCHADENSHOEHE_DURCHSCHNITT,
tooltip = paste("Bezirk: ", BEZ,
"<br>Durchschnitt Schadenshöhe: ",
round(SCHADENSHOEHE_DURCHSCHNITT, 2)))) +
geom_bar_interactive(stat = "identity", position = "dodge") +
scale_fill_gradient(low = "blue", high = "red") + # Farbverlauf
labs(
title = "Schadenshöhe der Fahrraddiebstähle je Bezirk",
x = "Bezirk",
y = "Schadenshöhe"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
# Rückgabe des interaktiven ggplot-Objekts
girafe(ggobj = p)
Die Karte zeigt, dass die Schadenshöhe in den verschiedenen Bezirksregionen von Berlin ähnlich verteilt ist wie die Karte der “Durchschnittlichen Fahrraddiebstähle in Berlin: Bezirksregion”. Bei genauerer Betrachtung fallen jedoch Unterschiede auf. Da eine Analyse aller Bezirksregionen sehr umfangreich wäre, konzentriert sich die nächste Analyse auf die Bezirke, um die Korrelation zwischen der Anzahl der Fahrraddiebstähle und der Schadenshöhe näher zu untersuchen. Dadurch können auch Rückschlüsse darauf gezogen werden, ob in den unterschiedlichen Bezirken unterschiedlich wertvolle Diebesgüter gestohlen wurden.
Bezirke
Die Karte und das Diagramm zeigen, dass Bezirk 05 die höchste durchschnittliche Schadenshöhe aufweist, während Bezirk 12 den niedrigsten Wert erzielt. Interessanterweise führt Bezirk 05 jedoch nicht das Diagramm der Fahrraddiebstähle an – hier hat Bezirk 10 den höchsten Wert. Diese Beobachtungen deuten darauf hin, dass die Korrelation zwischen der Anzahl der Fahrraddiebstähle und der Schadenshöhe nicht besonders stark ausgeprägt ist. In den Bezirken, die im Diagramm der Fahrraddiebstähle weiter hinten (in Richtung Rot) platziert sind, ist die Schadenshöhe tendenziell höher. Umgekehrt haben Bezirke, die weiter vorne (in Richtung Blau) positioniert sind, im Allgemeinen niedrigere Schadenshöhen. Dies könnte darauf hindeuten, dass in den Bezirken mit höherer Schadenshöhe tendenziell wertvollere oder mehrere Fahrräder gestohlen wurden.
Es ist wichtig zu betonen, dass bei der Berechnung der Schadenshöhe der Sachschaden nicht berücksichtigt wurde, wie zu Beginn bei der Beschreibung der Attribute erwähnt. Zudem wird ein Diebstahl, bei dem mehrere Fahrräder gestohlen wurden, nur als ein einziger Fahrraddiebstahl erfasst. Diese Unterschiede spiegeln sich auch in der Schadenshöhe wider.
Ein genauerer Blick auf die Karten zeigt, dass in Bezirken und Bezirksregionen, die eine intensivere Rottönung aufweisen als die Karte der durchschnittlichen Fahrraddiebstähle, die Schadenshöhe höher ausfällt. In blauer dargestellten Regionen sind die Schadenshöhen tendenziell niedriger, was darauf hindeutet, dass in diesen Gegenden häufiger mehrere Fahrräder oder teurere Fahrräder sowie zusätzliches Diebesgut gestohlen wurden. Wäre die Schadenshöhe in allen Bezirken gleich, würde die Karte der Schadenshöhe ein ähnliches Bild wie die Karte der durchschnittlichen Fahrraddiebstähle zeigen.
Die Analyse der Schadenshöhe bei Fahrraddiebstählen zeigt interessante Muster bezüglich der absoluten und durchschnittlichen Schadenshöhe nach Fahrradart sowie der regionalen Verteilung der Schäden.
Schadenshöhe nach Fahrradart: Die Gesamtschadenshöhe variiert je nach Fahrradart erheblich. Besonders auffällig ist das Herrenfahrrad, welches mit einer Gesamtschadenshöhe von 22.029.945 € den größten Anteil ausmacht, was mit einem durchschnittlichen Schaden von 1.244,63 € pro Fall einhergeht. Das Damenfahrrad folgt mit einem Gesamtschaden von 10.216.520 € und einem durchschnittlichen Schaden von 1.007,94 €. Im Vergleich dazu tragen Fahrräder allgemein 8.346.700 € zur Gesamtschadenshöhe bei, mit einem durchschnittlichen Schaden von 1.354,76 €. Kleinere Kategorien, wie diverse Fahrräder, haben eine Gesamtschadenshöhe von 2.517.623 € bei einem durchschnittlichen Schaden von 2.235,01 €. Schadenshöhe je Region/Bezirk: Bei der Betrachtung der regionalen Verteilung zeigt sich, dass die Schadenshöhe in den verschiedenen Bezirken Berlins stark variiert. Die Bezirksregionen wurden anhand der LOR (Lokalidentifier für Region) gruppiert, und die absoluten Schadenshöhen wurden summiert. Die Karte zur absoluten Schadenshöhe zeigt die Verteilung dieser Schäden, wobei größere Bezirksregionen deutlich höhere Schäden aufweisen. Eine detailliertere Untersuchung wurde durchgeführt, um den Zusammenhang zwischen Schadenshöhe und Einwohnerzahl zu ermitteln. Diese Analyse berücksichtigt nicht nur die absolute Schadenshöhe, sondern auch den durchschnittlichen Schaden pro Einwohner, was eine genauere Einschätzung der regionalen Verhältnisse ermöglicht. Durchschnittliche Schadenshöhe je Region/Bezirk: Die durchschnittliche Schadenshöhe wird berechnet, indem die Gesamtschadenshöhe durch die Einwohnerzahl des jeweiligen Bezirks oder der Bezirksregion geteilt wird. Dies ermöglicht eine Einschätzung der Schwere der Schäden relativ zur Bevölkerungszahl. Auf diese Weise wird deutlich, dass einige Regionen mit einer hohen Schadenshöhe pro Kopf auffallen, was auf eine höhere Häufigkeit oder Schwere der Fahrraddiebstähle in diesen Gebieten hindeutet. Die Karte zur durchschnittlichen Schadenshöhe zeigt diese Verhältnisse, wobei Bereiche mit besonders hohen Schäden pro Einwohner in rot und mit geringeren Schäden in blau markiert sind.
Die interaktive Visualisierung dieser Daten über Karten und Diagramme hilft dabei, tiefere Einblicke in die geografische und kategoriale Verteilung der Schäden zu gewinnen und gezielte Maßnahmen zur Prävention und Schadensbegrenzung zu ergreifen.
In diesem Kapitel werden die Zeiträume von Fahrraddiebstählen analysiert. Die Daten wurden in die Kategorien „Tagsüber“, „Nachts“ und „mehrere Tage“ unterteilt, wobei die Zuordnung anhand des Beginns des Diebstahls erfolgt. Die Diebstähle werden der Kategorie „Tagsüber“ zugeordnet, wenn sie zwischen 6:00 und 17:59 Uhr beginnen, der Kategorie „Nachts“, wenn sie zwischen 18:00 und 5:59 Uhr starten, und der Kategorie „mehrere Tage“, wenn der Diebstahl über 24 Stunden andauert.
fahrraddiebstahl_dauer_df <- fahrraddiebstahl_datensatz_df
# Umwandlung der Anfangszeiten
fahrraddiebstahl_dauer_df$TATZEIT_ANFANG <- as.POSIXct(
paste(fahrraddiebstahl_dauer_df$TATZEIT_ANFANG_DATUM, fahrraddiebstahl_dauer_df$TATZEIT_ANFANG_STUNDE),
format = "%d.%m.%Y %H", tz = "Europe/Berlin"
)
# Umwandlung der Endzeiten
fahrraddiebstahl_dauer_df$TATZEIT_ENDE <- as.POSIXct(
paste(fahrraddiebstahl_dauer_df$TATZEIT_ENDE_DATUM, fahrraddiebstahl_dauer_df$TATZEIT_ENDE_STUNDE),
format = "%d.%m.%Y %H", tz = "Europe/Berlin"
)
# Berechnung der Dauer in Stunden
fahrraddiebstahl_dauer_df$Dauer <- as.numeric(
difftime(fahrraddiebstahl_dauer_df$TATZEIT_ENDE, fahrraddiebstahl_dauer_df$TATZEIT_ANFANG, units = "hours"))
# Berechnung des Durchschnitts der allgemeinen Dauer
durchschnitt <- mean(fahrraddiebstahl_dauer_df$Dauer, na.rm = TRUE)
print(paste("Durchschnittszeit des Zeitraums eines Diebstahls beträgt:", durchschnitt))
## [1] "Durchschnittszeit des Zeitraums eines Diebstahls beträgt: 14.1767844378638"
Da der Zeitraum des Fahrraddiebstahls sich aus der Zeitspanne zwischen dem letzten Moment, in dem das Fahrrad gesehen wurde, und dem Zeitpunkt, an dem der Diebstahl bemerkt wurde, ergibt, ist diese Aussage wenig aussagekräftig. Sie gibt lediglich an, dass der durchschnittliche Zeitraum zwischen dem letzten Sichtung des Fahrrads, dem tatsächlichen Diebstahl und dem Moment, in dem der Diebstahl bemerkt wurde, etwa 14 Stunden beträgt.
# Zusammenfassungen für verschiedene Datenrahmen
allgemein_summary <- summary(fahrraddiebstahl_dauer_df$Dauer)
tagsüber_summary <- summary(fahrraddiebstahl_dauer_tagsüber_df$Dauer)
nachts_summary <- summary(fahrraddiebstahl_dauer_nachts_df$Dauer)
mehrere_tage_summary <- summary(fahrraddiebstahl_dauer_mehrere_tage_df$Dauer)
# Erstelle eine Tabelle für knitr
summary_table <- data.frame(
Zeitraum = c("Allgemein", "Tagsüber", "Nachts", "Mehrere Tage"),
Min = c(allgemein_summary[1], tagsüber_summary[1], nachts_summary[1], mehrere_tage_summary[1]),
"1st Qu." = c(allgemein_summary[2], tagsüber_summary[2], nachts_summary[2], mehrere_tage_summary[2]),
Median = c(allgemein_summary[3], tagsüber_summary[3], nachts_summary[3], mehrere_tage_summary[3]),
Mean = c(allgemein_summary[4], tagsüber_summary[4], nachts_summary[4], mehrere_tage_summary[4]),
"3rd Qu." = c(allgemein_summary[5], tagsüber_summary[5], nachts_summary[5], mehrere_tage_summary[5]),
Max = c(allgemein_summary[6], tagsüber_summary[6], nachts_summary[6], mehrere_tage_summary[6])
)
# Tabelle anzeigen
kable(summary_table, caption = "Zusammenfassungen der Diebstahlsdauerzeiten")
| Zeitraum | Min | X1st.Qu. | Median | Mean | X3rd.Qu. | Max |
|---|---|---|---|---|---|---|
| Allgemein | 0 | 3 | 9 | 14.176784 | 18 | 73 |
| Tagsüber | 0 | 2 | 6 | 7.328062 | 11 | 24 |
| Nachts | 0 | 2 | 10 | 9.270391 | 14 | 24 |
| Mehrere Tage | 25 | 34 | 43 | 45.001251 | 55 | 73 |
Diese Analyse zeigt, dass die kürzeste Zeit, in der ein Diebstahl bemerkt wurde, sowohl tagsüber als auch nachts bei 0 Stunden liegen kann, was bedeutet, dass der Diebstahl in derselben Stunde entdeckt wurde. Der längste Zeitraum beträgt 73 Stunden. Dies widerspricht jedoch der Angabe in der Datensatzbeschreibung, die besagt, dass Zeiträume von mehr als 72 Stunden nicht erfasst werden. Daher wird dieser Punkt weiter untersucht.
# Zeilen filtern, bei denen die Dauer größer als 72 Stunden ist
fahrraddiebstahl_dauer_df[fahrraddiebstahl_dauer_df$Dauer > 72, ]
Der Datensatz scheint auf den ersten Blick nur einen Zeitraum von 72 Stunden zu umfassen. Eine genauere Untersuchung zeigt jedoch, dass am Sonntag, dem 29. Oktober 2023, eine Zeitumstellung stattgefunden hat (Quelle: BMWK). Dadurch ergibt sich ein Zeitraum von tatsächlich 73 Stunden. Die Funktion “difftime” hat diese Zeitumstellung berücksichtigt, was den korrekten maximalen Wert von 73 Stunden erklärt. Die ursprüngliche Datensatzbeschreibung ist daher ungenau, da sie die Zeitumstellung nicht berücksichtigt hat.
# Tagsüber
ggplot(data = fahrraddiebstahl_dauer_tagsüber_df, aes(x = Dauer)) +
geom_bar(fill = "cyan4") +
labs(
title = "Verteilung der Diebstahldauer tagsüber",
x = "Dauer (Stunden)",
y = "Anzahl der Fälle"
) +
scale_x_continuous(breaks = seq(0, max(fahrraddiebstahl_dauer_tagsüber_df$Dauer), by = 1),
labels = function(x) ifelse(x == 0, "<1", x)) +
theme_minimal()
# Nachts
ggplot(data = fahrraddiebstahl_dauer_nachts_df, aes(x = Dauer)) +
geom_bar(fill = "cyan4") +
labs(
title = "Verteilung der Diebstahldauer nachts",
x = "Dauer (Stunden)",
y = "Anzahl der Fälle"
) +
scale_x_continuous(breaks = seq(0, max(fahrraddiebstahl_dauer_nachts_df$Dauer), by = 1),
labels = function(x) ifelse(x == 0, "<1", x)) +
theme_minimal()
# mehrere Tage
ggplot(data = fahrraddiebstahl_dauer_mehrere_tage_df, aes(x = Dauer)) +
geom_bar(fill = "cyan4") +
labs(
title = "Verteilung der Diebstahldauer mehrere Tage",
x = "Dauer (Stunden)",
y = "Anzahl der Fälle"
) +
scale_x_continuous(
breaks = seq(0, max(fahrraddiebstahl_dauer_mehrere_tage_df$Dauer), by = 5),
labels = function(x) ifelse(x == 0, "<1", paste(x, "h")),
expand = c(0, 0)
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1), # Schräg stellen für bessere Lesbarkeit
axis.title.x = element_text(size = 12, face = "bold"),
axis.title.y = element_text(size = 12, face = "bold")
)
Tagsüber: Die meisten Diebstähle, die tagsüber begannen, wurden innerhalb der ersten Stunde bemerkt. Im Verlauf des Tages nimmt die Zahl der Diebstähle, die bemerkt werden, bis zur 13. Stunde ab. Eine Ausnahme bilden dabei die 8. und 9. Stunde, in denen ein Anstieg zu verzeichnen ist. Bis zur 15. Stunde kommt es zu einem weiteren, kurzen Anstieg. Ab der 16. Stunde sinken die Werte kontinuierlich, wobei in den Stunden 21, 23 und 24 noch einmal leichte Anstiege zu beobachten sind.
Nachts: Auch nachts werden die meisten Diebstähle innerhalb der ersten Stunde bemerkt. Danach sinken die Werte bis zur 6. Stunde deutlich. Ab der 7. Stunde steigt die Zahl der bemerkten Diebstähle wieder stark an, bis zur 13. Stunde. Ab der 14. Stunde fallen die Werte erneut stark ab. Der Anstieg in den frühen Morgenstunden lässt sich damit erklären, dass die betroffene Person vermutlich den Schlaf beendet und den Diebstahl erst dann bemerkt hat.
Mehrere Tage: Im Zeitraum von 25 bis 35 Stunden lässt sich ein abfallender Trend beobachten. Von der 35. bis zur 50. Stunde steigt der Wert stark an, bleibt jedoch deutlich unter dem Höhepunkt der 25. Stunde. Zwischen der 50. und 60. Stunde tritt ein weiterer Tiefpunkt auf. Ab etwa der 62. Stunde stabilisiert sich der Wert und pendelt sich zwischen 100 und 150 Fällen ein. Ein möglicher Einflussfaktor für diese Schwankungen könnte das Wochenmuster sein, weshalb eine detailliertere Analyse der Wochentage sinnvoll wäre.
# Sicherstellen, dass die Wochentag-Spalte erstellt wird
fahrraddiebstahl_dauer_df <- fahrraddiebstahl_dauer_df %>%
mutate(
Wochentag = weekdays(TATZEIT_ANFANG), # Wochentag aus TATZEIT_ANFANG berechnen
Stunde = floor(Dauer) # Dauer in ganze Stunden umwandeln
)
# Daten vorbereiten: Häufigkeit je Wochentag und Stunde berechnen
fahrraddiebstahl_dauer_wochentag_df <- fahrraddiebstahl_dauer_df %>%
mutate(Stunde = floor(Dauer)) %>% # Dauer in ganze Stunden umwandeln
group_by(Wochentag, Stunde) %>%
summarise(Häufigkeit = n(), .groups = 'drop')
# Diagramm erstellen
ggplot(data = fahrraddiebstahl_dauer_wochentag_df, aes(x = Wochentag, y = Stunde, size = Häufigkeit, color = Häufigkeit)) +
geom_point(alpha = 0.7) +
scale_x_discrete(
limits = c("Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag")
) +
scale_y_continuous(
breaks = seq(0, 72, by = 6), # Intervalle von 6 Stunden
labels = function(x) paste0(x, "h") # Beschriftung mit "h" für Stunden
) +
scale_size_continuous(range = c(2, 10), name = "Häufigkeit") + # Größe der Kreise skalieren
scale_color_gradient(low = "blue", high = "red", name = "Häufigkeit") + # Farbverlauf von Blau zu Rot
labs(
title = "Fahrraddiebstahldauer nach Wochentag und Stunde",
x = "Wochentag",
y = "Dauer (Stunden)"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
axis.title.x = element_text(size = 12, face = "bold"),
axis.title.y = element_text(size = 12, face = "bold"),
axis.text.y = element_text(size = 10)
)
## Warning: Removed 1 row containing missing values or values outside the scale range
## (`geom_point()`).
Die Werte am Freitag und Samstag ab der 36. Stunde zeigen auffällig höhere Spitzen im Vergleich zu den übrigen Tagen von Sonntag bis Donnerstag. Besonders ausgeprägt ist der Anstieg am Freitag ab der 60. Stunde. Rechnet man 60 Stunden ab Freitag, landet man beim Montag, was auf einen Zusammenhang hindeutet. Ähnlich verhält es sich mit den Samstagswerten: Bei einer Hochrechnung von 42 Stunden landet man ebenfalls am Montag. Diese Muster legen nahe, dass Diebstähle, die am Wochenende stattgefunden haben, häufig erst am Montag bemerkt wurden.
Um die genaue Ursache für dieses Phänomen zu ermitteln, wäre eine eingehendere Untersuchung des Fahrradverkehrs und der Aktivitäten der Berliner Bürger notwendig. Möglicherweise hängt es mit dem Wochenendverhalten zusammen, wie etwa dem Wegfahren oder der unbemerkten Abwesenheit von zu Hause. In vielen Fällen wird ein Fahrraddiebstahl erst dann bemerkt, wenn die Betroffenen das Fahrrad am Montag wieder benötigen, um zur Arbeit oder zu anderen Verpflichtungen zu fahren.
Eine weiterführende Untersuchung wird im Rahmen dieser Analyse nicht durchgeführt, da die erforderlichen Daten nicht vorliegen und eine solche Analyse den Umfang dieser Untersuchung deutlich überschreiten würde.
Die Analyse zeigt, dass es bestimmte Zeiträume und Wochentage gibt, an denen Diebstähle häufiger festgestellt werden, was auf spezifische Verhaltensmuster hinweist. Besonders auffällig sind die erhöhten Zahlen an Wochenenden, was möglicherweise auf eine verzögerte Entdeckung von Diebstählen gegen Ende des Wochenendes hinweist.
Darüber hinaus zeigt die Analyse, dass Diebstähle häufig eine Dauer von weniger als einer Stunde aufweisen, wobei diese Zeitspanne mit den meisten Fällen korreliert. Dieses Ergebnis könnte für die Untersuchung der Tatzeiten von Bedeutung sein, da diese spezifischen Zeitdauern einer bestimmten Uhrzeit (in Stunden) zugeordnet werden können.
Mit diesem Kapitel der Datenanalyse sollen präferierte Tatzeiten herausgefunden werden.
fahrraddiebstahl_anzahl_df <- fahrraddiebstahl_datensatz_df
# Convert `TATZEIT_ANFANG_STUNDE` to numeric to avoid NA errors
fahrraddiebstahl_anzahl_df$TATZEIT_STUNDE_ANZAHL <- as.numeric(fahrraddiebstahl_anzahl_df$TATZEIT_ANFANG_STUNDE)
# Konvertiere `TATZEIT_ANFANG_STUNDE` in numerisch, um Fehler mit NA-Werten zu vermeiden
fahrraddiebstahl_anzahl_df$TATZEIT_STUNDE_ANZAHL <- as.numeric(fahrraddiebstahl_datensatz_df$TATZEIT_ANFANG_STUNDE)
stunden_anzahl <- fahrraddiebstahl_anzahl_df %>%
filter(!is.na(TATZEIT_STUNDE_ANZAHL)) %>% # NA-Werte entfernen
group_by(TATZEIT_STUNDE_ANZAHL) %>%
summarise(Anzahl = n())
# Plot als Balkendiagramm
ggplot(stunden_anzahl, aes(x = TATZEIT_STUNDE_ANZAHL, y = Anzahl)) +
geom_bar(stat = "identity", fill = "cyan4") +
labs(
title = "Absolute Anzahl der Anfänge von Fahrraddiebstählen je Stunde",
x = "Stunde des Tages",
y = "Anzahl der Fälle"
) +
theme_minimal()
Das Diagramm veranschaulicht die Häufigkeit der Diebstähle zu den verschiedenen geschätzten Anfangszeiten. Aufgrund der Ungenauigkeit dieser Uhrzeiten bei längeren Tatdauern ist die Aussagekraft jedoch eingeschränkt. Die Analyse der Dauer hat jedoch ergeben, dass in einigen Fällen mehrere Diebstähle innerhalb derselben Stunde erfasst wurden. Diese Daten können daher herausgefiltert werden, um präzisere Aussagen über die tatsächlichen Tatzeiten zu ermöglichen.
# Filtere die Datensätze mit DAUER < 1
fahrraddiebstahl_anzahl_df_beschränkte_dauer <- fahrraddiebstahl_dauer_df %>%
filter(Dauer == 0)
# Konvertiere `TATZEIT_ANFANG_STUNDE` in numerisch, um Fehler mit NA-Werten zu vermeiden
fahrraddiebstahl_anzahl_df_beschränkte_dauer$TATZEIT_STUNDE_ANZAHL <- as.numeric(fahrraddiebstahl_anzahl_df_beschränkte_dauer$TATZEIT_ANFANG_STUNDE)
# Entferne NA-Werte und gruppiere nach Stunden
stunden_anzahl_beschränkte_dauer <- fahrraddiebstahl_anzahl_df_beschränkte_dauer %>%
filter(!is.na(TATZEIT_STUNDE_ANZAHL)) %>% # NA-Werte entfernen
group_by(TATZEIT_STUNDE_ANZAHL) %>%
summarise(Anzahl = n())
# Plot als Balkendiagramm für Diebstähle mit Dauer 0
ggplot(stunden_anzahl_beschränkte_dauer, aes(x = TATZEIT_STUNDE_ANZAHL, y = Anzahl)) +
geom_bar(stat = "identity", fill = "cyan4") +
labs(
title = "Präferierte Uhrzeiten von Fahrraddiebstählen (in Stunde)",
x = "Stunde des Tages",
y = "Anzahl der Fälle"
) +
theme_minimal()
Das Diagramm zeigt die Häufigkeit von Fahrraddiebstählen im Verlauf eines Tages. Die x-Achse ist in Stunden unterteilt (von 0 bis 24 Uhr), während die y-Achse die Anzahl der Diebstähle darstellt. Ziel der Analyse war es, präferierte Uhrzeiten für Fahrraddiebstähle zu identifizieren. Dabei wurden ausschließlich Datensätze berücksichtigt, deren Dauer weniger als eine Stunde beträgt.
Höchstwerte: Die meisten Diebstähle ereignen sich am Nachmittag und frühen Abend, insbesondere zwischen 14 und 19 Uhr. Ein markanter Peak tritt um 16 Uhr auf. Tiefwerte: In den frühen Morgenstunden (zwischen 2 und 5 Uhr) sowie in den späten Abendstunden (nach 21 Uhr) sind Fahrraddiebstähle seltener. Allgemeiner Trend: Die Häufigkeit der Diebstähle steigt stetig von den frühen Morgenstunden an, erreicht ihren Höhepunkt am Nachmittag und nimmt danach wieder ab.
Das Ergebnis zeigt, dass Fahrraddiebstähle besonders häufig um 17 Uhr auftreten, während sie um 5 Uhr weniger bevorzugt sind. Der markante Höhepunkt um 17 Uhr war im Diagramm deutlich sichtbar, unabhängig von der Dauer der Tatzeiträume. In den Nachtstunden hingegen sind die Werte schwerer zu interpretieren, da Betroffene den Diebstahl möglicherweise im Schlaf nicht bemerken. Eine Erweiterung der Zeitintervalle würde hier keine neuen Erkenntnisse bringen, da die Schlafdauer individuell stark variiert. Betrachtet man jedoch beide Diagramme statistisch, lässt sich feststellen, dass nachts insgesamt weniger Fahrraddiebstähle verzeichnet werden, wodurch der Tiefpunkt um 5 Uhr weiterhin Bestand haben kann.
Um mehr Daten einzubeziehen, wurde die Toleranz der Zeitdauer auf 3 Stunden (≤2) erhöht. Dadurch wird ein großer Anteil der Fälle abgedeckt, wie die Diagramme der Zeitdauern zeigen. Ob diese Anpassung die präferierten Uhrzeiten wesentlich beeinflusst, wird im folgenden Diagramm verdeutlicht.
# Filtere die Datensätze mit DAUER <= 2
fahrraddiebstahl_anzahl_df_beschränkte_dauer <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 2)
# Konvertiere `TATZEIT_ANFANG_STUNDE` in numerisch, um Fehler mit NA-Werten zu vermeiden
fahrraddiebstahl_anzahl_df_beschränkte_dauer$TATZEIT_STUNDE_ANZAHL <- as.numeric(fahrraddiebstahl_anzahl_df_beschränkte_dauer$TATZEIT_ANFANG_STUNDE)
# Entferne NA-Werte und gruppiere nach Stunden
stunden_anzahl_beschränkte_dauer <- fahrraddiebstahl_anzahl_df_beschränkte_dauer %>%
filter(!is.na(TATZEIT_STUNDE_ANZAHL)) %>% # NA-Werte entfernen
group_by(TATZEIT_STUNDE_ANZAHL) %>%
summarise(Anzahl = n())
# Plot als Balkendiagramm für Diebstähle mit Dauer 0
ggplot(stunden_anzahl_beschränkte_dauer, aes(x = TATZEIT_STUNDE_ANZAHL, y = Anzahl)) +
geom_bar(stat = "identity", fill = "cyan4") +
labs(
title = "Präferierte Uhrzeiten von Fahrraddiebstählen (in Stunde)",
x = "Stunde des Tages",
y = "Anzahl der Fälle"
) +
theme_minimal()
Die Analyse zeigt, dass der Verlauf des Diagramms im Zeitraum <1 weitgehend unverändert bleibt, auch wenn die Toleranz auf 3 Stunden erweitert wird. Dadurch ändern sich die präferierten Uhrzeiten nicht signifikant. Die absolute Anzahl der Fälle nimmt jedoch deutlich zu, was zu einem größeren und aussagekräftigeren Datensatz führt.
Dieses Ergebnis unterstreicht, dass die Untersuchung von Dauern <1 gut geeignet ist, um präferierte Uhrzeiten zu identifizieren. Gleichzeitig zeigt es, dass für weiterführende Analysen der Datensatz mit einer Toleranz von ≤2 sinnvoll genutzt werden kann, um von der erhöhten Datenmenge zu profitieren.
# Filtere die Datensätze mit DAUER <=2
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 2)
# Datensatz nach Bezirk und Stunde gruppieren, nur mit den ersten 6 Zeichen von LOR
lor_zeit_anzahl <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(LOR = substr(LOR, 1, 6)) %>% # Nur die ersten 6 Zeichen von LOR verwenden
group_by(LOR, TATZEIT_ANFANG_STUNDE) %>%
summarise(anzahl_diebstahl = n(), .groups = "drop") %>%
arrange(LOR, desc(anzahl_diebstahl))
# Höchste und zweitmeiste Diebstähle pro LOR ermitteln
lor_max_zeit <- lor_zeit_anzahl %>%
group_by(LOR) %>%
summarise(
max_anzahl = max(anzahl_diebstahl),
max_zeit = TATZEIT_ANFANG_STUNDE[which.max(anzahl_diebstahl)],
zweitmax_anzahl = ifelse(n() > 1, sort(anzahl_diebstahl, decreasing = TRUE)[2], NA),
zweitmax_zeit = ifelse(n() > 1, TATZEIT_ANFANG_STUNDE[order(anzahl_diebstahl, decreasing = TRUE)][2], NA),
.groups = "drop"
)
# Zusammenführen der Fahrraddiebstahldaten mit den Bezirksdaten
berlin_map_bezirksregion <- berlin_map %>%
left_join(lor_max_zeit, by = c("BZR_ID" = "LOR"))
# Erstelle die interaktive Karte mit ggiraph
p_reg_ggiraph <- ggplot(data = berlin_map_bezirksregion) +
geom_sf_interactive(aes(
fill = factor(max_zeit), # Farbe nach der Stunde mit den meisten Diebstählen
tooltip = paste0(
"Bezirk: ", BZR_NAME,
"<br>Höchste Fälle um ", max_zeit, " Uhr: ", max_anzahl, " Fälle",
"<br>Zweitmeiste Fälle um ", zweitmax_zeit, " Uhr: ", zweitmax_anzahl, " Fälle"
), # Tooltip-Inhalt
data_id = BZR_NAME # Interaktive ID für Bezirksregionen
), color = "black") +
scale_fill_viridis_d(name = "Uhrzeit") + # Alternativ: Verwende das "viridis"-Farbschema
theme_minimal() +
labs(
title = "Fahrraddiebstähle in Berlin: Bezirke und Uhrzeiten",
subtitle = "Uhrzeit mit den meisten Diebstählen (Uhrzeit Anfang) pro Bezirk",
caption = "Quelle: Fahrraddiebstahl-Datensatz"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_reg_ggiraph <- girafe(ggobj = p_reg_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_reg_ggiraph <- girafe_options(
interactive_map_reg_ggiraph,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_reg_ggiraph
Die Karte zeigt die Verteilung von Fahrraddiebstählen in Berlin nach Bezirken und den zugehörigen Uhrzeiten. Die verschiedenen Farben repräsentieren die Uhrzeit, zu der in einem Bezirk die meisten Diebstähle verzeichnet wurden. Die gut unterscheidbaren Farben verdeutlichen, dass die bevorzugten Tatzeiten je Bezirksregion variieren. Auffällig ist jedoch, dass die meisten Diebstähle überwiegend am Nachmittag stattfinden – ein Muster, das bereits in den vorherigen Diagrammen festgestellt wurde.
Eine besondere Bezirksregion auf der Karte ist “Schmöckwitz”. Hier wurden keine Fahrraddiebstähle registriert, die innerhalb einer Zeitdauer von höchstens 2 Minuten begangen wurden. Um auch für diesen Bezirk Ergebnisse zu erhalten, könnte es sinnvoll sein, die analysierte Zeitdauer etwas zu erhöhen.
Da für die Bezirksregion “Schmöckwitz” bei einer Dauer von ≤ 2 Stunden keine Fahrraddiebstahldaten vorhanden sind, muss die Toleranz für die Dauer angepasst werden. Zunächst wird die minimale Dauer berechnet, die erforderlich ist, um für Schmöckwitz Daten zu finden. Es ist dabei zu berücksichtigen, dass Schmöckwitz lediglich maximal 10 Fälle aufweist, was sich auch in der vorherigen Analyse der absoluten Anzahl an Fahrraddiebstählen pro Bezirk gezeigt hat.
# LOR-Substring für den Bezirk "Schmöckwitz" finden
lor_schmoeckwitz <- berlin_map %>%
filter(BZR_NAME == "Schmöckwitz") %>%
pull(BZR_ID) %>%
substr(1, 6) # Nur die ersten 6 Zeichen extrahieren
# Gruppieren und Zusammenfassen der Diebstahldaten basierend auf dem Substring
schmoeckwitz_daten <- fahrraddiebstahl_dauer_df %>%
filter(substr(LOR, 1, 6) == lor_schmoeckwitz) %>% # Filtern nach passendem LOR-Substring
group_by(LOR_Substring = substr(LOR, 1, 6)) %>% # Gruppieren nach Substring
summarise(
minimale_dauer = min(Dauer, na.rm = TRUE), # Kleinste Dauer berechnen
maximale_dauer = max(Dauer, na.rm = TRUE), # Maximale Dauer berechnen
anzahl_faelle = n(), # Anzahl der Fälle
.groups = "drop"
)
# Tabelle für knitr erstellen
knitr::kable(schmoeckwitz_daten, caption = "Zusammenfassung der Fahrraddiebstähle in Schmöckwitz")
| LOR_Substring | minimale_dauer | maximale_dauer | anzahl_faelle |
|---|---|---|---|
| 093012 | 4 | 26 | 10 |
Die minimale Dauer, bei der für Schmöckwitz Daten übermittelt werden, liegt bei ≤ 4 Stunden. Da die Gesamtzahl der Fälle in diesem Bezirk 10 beträgt, wurde der relevante Datensatz korrekt identifiziert. Nun gilt es, zu bewerten, ob die Erhöhung der Toleranz auf ≤ 4 Stunden eine signifikante Abweichung im Verlauf der präferierten Uhrzeiten im Vergleich zu den Daten mit einer Dauer von <1 Stunde darstellt. Dies soll durch die folgende grafische Darstellung veranschaulicht werden.
# Filtere die Datensätze mit DAUER <= 4
fahrraddiebstahl_anzahl_df_beschränkte_dauer <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 4)
# Konvertiere `TATZEIT_ANFANG_STUNDE` in numerisch, um Fehler mit NA-Werten zu vermeiden
fahrraddiebstahl_anzahl_df_beschränkte_dauer$TATZEIT_STUNDE_ANZAHL <- as.numeric(fahrraddiebstahl_anzahl_df_beschränkte_dauer$TATZEIT_ANFANG_STUNDE)
# Entferne NA-Werte und gruppiere nach Stunden
stunden_anzahl_beschränkte_dauer <- fahrraddiebstahl_anzahl_df_beschränkte_dauer %>%
filter(!is.na(TATZEIT_STUNDE_ANZAHL)) %>% # NA-Werte entfernen
group_by(TATZEIT_STUNDE_ANZAHL) %>%
summarise(Anzahl = n())
# Plot als Balkendiagramm für Diebstähle mit Dauer 0
ggplot(stunden_anzahl_beschränkte_dauer, aes(x = TATZEIT_STUNDE_ANZAHL, y = Anzahl)) +
geom_bar(stat = "identity", fill = "cyan4") +
labs(
title = "Präferierte Uhrzeiten von Fahrraddiebstählen (in Stunde)",
x = "Stunde des Tages",
y = "Anzahl der Fälle"
) +
theme_minimal()
Tatsächlich zeigt sich, dass sich der Datensatz bei einer Toleranz von 4 Stunden stärker unterscheidet. Ein solches Intervall für die Erfassung von Fahrraddiebstählen erscheint zu hoch und verzerrt die Ergebnisse hinsichtlich der präferierten Uhrzeiten. Daher ist es nicht sinnvoll, die Toleranz auf ≤ 4 Stunden zu erhöhen. Die Bezirksregion Schmöckwitz sollte daher als Ausnahme betrachtet werden. Dennoch wurde zur Vollständigkeit eine Karte mit der erhöhten Toleranz (≤ 4 Stunden) erstellt.
# Filtere die Datensätze mit DAUER <=2
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 4)
# Datensatz nach Bezirk und Stunde gruppieren, nur mit den ersten 6 Zeichen von LOR
lor_zeit_anzahl <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(LOR = substr(LOR, 1, 6)) %>% # Nur die ersten 6 Zeichen von LOR verwenden
group_by(LOR, TATZEIT_ANFANG_STUNDE) %>%
summarise(anzahl_diebstahl = n(), .groups = "drop") %>%
arrange(LOR, desc(anzahl_diebstahl))
# Höchste und zweitmeiste Diebstähle pro LOR ermitteln
lor_max_zeit <- lor_zeit_anzahl %>%
group_by(LOR) %>%
summarise(
max_anzahl = max(anzahl_diebstahl),
max_zeit = TATZEIT_ANFANG_STUNDE[which.max(anzahl_diebstahl)],
zweitmax_anzahl = ifelse(n() > 1, sort(anzahl_diebstahl, decreasing = TRUE)[2], NA),
zweitmax_zeit = ifelse(n() > 1, TATZEIT_ANFANG_STUNDE[order(anzahl_diebstahl, decreasing = TRUE)][2], NA),
.groups = "drop"
)
# Zusammenführen der Fahrraddiebstahldaten mit den Bezirksdaten
berlin_map_bezirksregion <- berlin_map %>%
left_join(lor_max_zeit, by = c("BZR_ID" = "LOR"))
# Erstelle die interaktive Karte der Bezirke basierend auf den maximalen und zweitgrößten Diebstählen pro LOR
p_reg_ggiraph <- ggplot(data = berlin_map_bezirksregion) +
geom_sf_interactive(aes(
fill = factor(max_zeit), # Farbe nach der Stunde mit den meisten Diebstählen
tooltip = paste0(
"Bezirk: ", BZR_NAME,
"<br>Höchste Fälle um ", max_zeit, " Uhr: ", max_anzahl, " Fälle",
"<br>Zweitmeiste Fälle um ", zweitmax_zeit, " Uhr: ", zweitmax_anzahl, " Fälle"
), # Tooltip-Inhalt
data_id = BZR_ID # Interaktive ID für Bezirke
), color = "black") +
scale_fill_viridis_d(name = "Uhrzeit") + # Viridis Farbschema
theme_minimal() +
labs(
title = "Fahrraddiebstähle in Berlin: Bezirke und Uhrzeiten",
subtitle = "Uhrzeit mit den meisten Diebstählen (Uhrzeit Anfang) pro Bezirk",
caption = "Quelle: Fahrraddiebstahl-Datensatz"
)
# Erstelle die ggiraph-Visualisierung
interactive_map_reg <- girafe(ggobj = p_reg_ggiraph)
# Passe ggiraph-Einstellungen an (optional)
interactive_map_reg <- girafe_options(
interactive_map_reg,
opts_hover(css = "fill:grey;cursor:pointer;"),
opts_tooltip(css = "background-color:white;color:black;padding:5px;border-radius:5px;")
)
# Zeige die interaktive Karte
interactive_map_reg
Bei dieser Dauer liegt lediglich ein Fall vor, der um 16 Uhr beginnt und um 20 Uhr endet. Mit dieser Information kann jedoch wenig erreicht werden, da dieses lange Intervall keine zuverlässigen Rückschlüsse auf präferierte Uhrzeiten zulässt.
In diesem Kapitel werden die Diebstahlszahlen an verschiedenen Tagen und Monaten analysiert. Dabei wird das Datum des Diebstahls, also das “TATZEIT_ENDE_DATUM”, berücksichtigt. Die maximale Dauer für einen Diebstahl liegt bei drei Tagen, da längere Zeiträume nicht im Datensatz enthalten sind. Eine Abweichung von drei Tagen ist aus der Perspektive von Jahr und Monat vernachlässigbar. Für die Analyse der präferierten Wochentage sollte jedoch die Dauer auf maximal einen Tag beschränkt werden, da der Diebstahl andernfalls auch an einem anderen Wochentag stattgefunden haben könnte.
# Annahme: fahrraddiebstahl_datensatz_df enthält eine Spalte `TATZEIT_ANFANG_DATUM` im Format "%d.%m.%Y"
fahrraddiebstahl_datensatz_Anzahl_df <- fahrraddiebstahl_datensatz_df %>%
mutate(
TATZEIT_DATUM_ANZAHL = as.Date(TATZEIT_ENDE_DATUM, format = "%d.%m.%Y"), # Konvertierung zu Datum
Monat = month(TATZEIT_DATUM_ANZAHL, label = TRUE, abbr = TRUE) # Extrahiere den Monat
)
# Gruppiere nach `TATZEIT_DATUM_ANZAHL` und zähle die Anzahl der Fälle je Datum
datum_anzahl <- fahrraddiebstahl_datensatz_Anzahl_df %>%
filter(!is.na(TATZEIT_DATUM_ANZAHL)) %>% # NA-Werte entfernen
group_by(TATZEIT_DATUM_ANZAHL, Monat) %>% # Gruppiere auch nach Monat
summarise(Anzahl = n(), .groups = "drop")
# Plot mit unterschiedlichen Farben für die Monate
ggplot(datum_anzahl, aes(x = TATZEIT_DATUM_ANZAHL, y = Anzahl, fill = Monat)) +
geom_bar(stat = "identity") +
labs(
title = "Fälle von Fahrraddiebstählen je Datum",
x = "Datum",
y = "Anzahl der Fälle",
fill = "Monat"
) +
theme_minimal()
Das Diagramm zeigt die absolute Anzahl der Fahrraddiebstähle pro Tag, basierend auf dem gesamten Datensatz. Der Tag wird durch das angegebene Anfangsdatum des jeweiligen Tatzeitraums bestimmt. Es ist deutlich erkennbar, dass die Anzahl der Diebstähle während der Sommermonate ansteigt. Eine plausible Erklärung hierfür ist, dass in dieser Zeit mehr Menschen unterwegs sind, was die Wahrscheinlichkeit von Fahrraddiebstählen erhöht.
# Filtere die Datensätze mit DAUER <=24
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 24)
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(
TATZEIT_DATUM_ANZAHL = as.Date(TATZEIT_ANFANG_DATUM, format = "%d.%m.%Y"), # Konvertierung zu Datum
Monat = month(TATZEIT_DATUM_ANZAHL, label = TRUE, abbr = TRUE), # Extrahiere den Monat
Wochentag = wday(TATZEIT_DATUM_ANZAHL, label = TRUE) # Extrahiere den Wochentag
)
# Gruppiere nach `Wochentag` und `Monat` und zähle die Anzahl der Fälle je Wochentag und Monat
wochentag_monat_anzahl <- fahrraddiebstahl_beschränkte_dauer_df %>%
filter(!is.na(TATZEIT_DATUM_ANZAHL)) %>% # Filtere NA-Werte
group_by(Wochentag, Monat) %>% # Gruppiere nach Wochentag und Monat
summarise(Anzahl = n(), .groups = "drop")
# Erstelle das Plot
ggplot(wochentag_monat_anzahl, aes(x = Wochentag, y = Anzahl, fill = Monat)) +
geom_bar(stat = "identity", position = "dodge") +
labs(
title = "Anzahl der Fahrraddiebstähle pro Wochentag und Monat",
x = "Wochentag",
y = "Anzahl der Diebstähle",
fill = "Monat"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Das Diagramm zeigt die Anzahl der Fahrraddiebstähle in Abhängigkeit von Wochentag und Monat. Hierbei wurden ausschließlich Tatzeiträume berücksichtigt, die maximal einen Tag umfassten, um eine Vermischung der Wochentage zu vermeiden.
Saisonalität: Wie auch im vorherigen Diagramm ist eine saisonale Schwankung der Diebstähle erkennbar. Besonders in den wärmeren Monaten (Mai bis August) steigt die Zahl der Diebstähle, während sie in den kälteren Monaten tendenziell sinkt. Wochentagsabhängigkeit: Ein eindeutiger Trend hinsichtlich bestimmter Wochentage lässt sich nicht erkennen. Die Anzahl der Diebstähle variiert zwar, jedoch ohne eine klare Tendenz für bestimmte Wochentage. Monatliche Schwankungen: Auch innerhalb eines Monats gibt es Schwankungen in der Zahl der Diebstähle, jedoch sind diese weniger ausgeprägt als die saisonalen Unterschiede.
# Filtere die Datensätze mit DAUER <=24
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 24)
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(
TATZEIT_DATUM_ANZAHL = as.Date(TATZEIT_ANFANG_DATUM, format = "%d.%m.%Y"), # Konvertierung zu Datum
Wochentag = wday(TATZEIT_DATUM_ANZAHL, label = TRUE) # Extrahiere den Wochentag
)
# Gruppiere nach `Wochentag` und zähle die Anzahl der Fälle je Wochentag über alle Monate hinweg
wochentag_anzahl <- fahrraddiebstahl_beschränkte_dauer_df %>%
filter(!is.na(TATZEIT_DATUM_ANZAHL)) %>% # Filtere NA-Werte
group_by(Wochentag) %>% # Gruppiere nur nach Wochentag
summarise(Anzahl = n(), .groups = "drop")
# Berechne die durchschnittliche Anzahl der Diebstähle pro Wochentag
durchschnitt_wochentag <- wochentag_anzahl %>%
mutate(Durchschnitt = Anzahl) # Berechne den Durchschnitt pro Wochentag
# Erstelle das Plot
ggplot(wochentag_anzahl, aes(x = Wochentag, y = Anzahl, fill = Wochentag)) +
geom_bar(stat = "identity") +
labs(
title = "Anzahl der Fahrraddiebstähle pro Wochentag (alle Monate)",
x = "Wochentag",
y = "Anzahl der Diebstähle"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Das Diagramm zeigt die Anzahl der Fahrraddiebstähle in Bezug auf die jeweiligen Wochentage, wobei ausschließlich Daten berücksichtigt wurden, deren Dauer einen Tag nicht überschreitet.
Höchste Diebstahlzahlen: Die meisten Diebstähle treten an den Werktagen Mittwoch und Donnerstag auf. Niedrigste Diebstahlzahlen: Am Wochenende, insbesondere samstags, sind die Diebstahlzahlen am niedrigsten. Allgemeiner Trend: Ein deutlicher Unterschied zwischen Werktagen (Montag bis Freitag) und dem Wochenende (Samstag und Sonntag) ist erkennbar. An Werktagen ist die Zahl der Diebstähle insgesamt höher.
Wie bereits in der Analyse der Zeiträume festgestellt, werden viele Fahrraddiebstähle an Wochenendtagen erst in der darauffolgenden Woche bemerkt, was zu der niedrigeren Anzahl an Diebstählen am Wochenende führt.
# Konvertiere TATZEIT_ANFANG_DATUM in Datum und extrahiere Monat und Jahr
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(
TATZEIT_DATUM_ANZAHL = as.Date(TATZEIT_ANFANG_DATUM, format = "%d.%m.%Y"), # Konvertiere TATZEIT_ANFANG_DATUM zu Datum
Jahr = year(TATZEIT_DATUM_ANZAHL), # Extrahiere das Jahr
Monat = month(TATZEIT_DATUM_ANZAHL, label = TRUE, abbr = TRUE) # Extrahiere den Monat
)
# Daten nach Monat und Jahr aggregieren
monat_jahr_anzahl <- fahrraddiebstahl_beschränkte_dauer_df %>%
filter(!is.na(TATZEIT_DATUM_ANZAHL)) %>%
group_by(Jahr, Monat) %>%
summarise(Anzahl = n(), .groups = "drop")
# Plot erstellen
ggplot(monat_jahr_anzahl, aes(x = Monat, y = Anzahl, fill = factor(Jahr))) +
geom_bar(stat = "identity", position = "dodge") +
scale_fill_brewer(palette = "Set1") + # Farbpalette für Jahre
labs(
title = "Fälle von Fahrraddiebstählen je Monat und Jahr",
x = "Monat",
y = "Anzahl der Fälle",
fill = "Jahr"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Optional: für bessere Lesbarkeit der Monatsnamen
Das Diagramm zeigt die Anzahl der Fahrraddiebstähle pro Monat für die Jahre 2023 und 2024. In Form eines Balkendiagramms wird die monatliche Variation der Diebstahlszahlen veranschaulicht. Die Balken sind nach Jahren farblich unterteilt, um einen direkten Vergleich zu ermöglichen. Für diese Analyse wurde der gesamte Datensatz verwendet, da eine umfassende Datenbasis angestrebt wird. Eine Verzerrung könnte jedoch auftreten, wenn ein erheblicher Teil der Tatzeiten in einem anderen Monat beginnt, als sie enden. Diese potenzielle Verzerrung wird im weiteren Verlauf dieses Unterkapitels genauer untersucht.
Saisonalität: Die Zahl der Fahrraddiebstähle weist ausgeprägte saisonale Schwankungen auf. In den wärmeren Monaten, etwa von April bis September, sind die Diebstähle deutlich häufiger, was auf den Einfluss des Wetters auf das Fahrradfahren und die damit verbundene Anfälligkeit für Diebstähle hinweist. Jährlicher Vergleich: Zwischen den Jahren 2023 und 2024 gibt es auffällige Unterschiede in den Diebstahlzahlen. In Monaten wie Mai und Juni 2024 wurden mehr Fahrräder gestohlen als im Vorjahr, während die Zahlen in anderen Monaten, etwa im Oktober, rückläufig waren. Insgesamt lässt sich jedoch ein ähnlicher saisonaler Verlauf in beiden Jahren erkennen. Höchstwerte: Die meisten Diebstähle traten in den Monaten Mai, Juni und Juli in beiden Jahren auf. Tiefstwerte: Die wenigsten Diebstähle wurden in den Wintermonaten (Dezember, Januar, Februar) verzeichnet.
# Filtern der Diebstähle mit Dauer <= 73 Stunden
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 73)
# Konvertiere TATZEIT_ANFANG und TATZEIT_ENDE in Jahr und Monat
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(
Jahr_Anfang = year(TATZEIT_ANFANG),
Monat_Anfang = month(TATZEIT_ANFANG, label = TRUE, abbr = TRUE),
Jahr_Ende = year(TATZEIT_ENDE),
Monat_Ende = month(TATZEIT_ENDE, label = TRUE, abbr = TRUE)
)
# Filtern nach Anfangsmonat != Endmonat und im selben Jahr
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_ueber_mehrere_monate %>%
filter(
!is.na(TATZEIT_ENDE),
Monat_Anfang != Monat_Ende,
Jahr_Anfang == Jahr_Ende
)
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_ueber_mehrere_monate %>%
mutate(
# Berechne, wie viele Stunden der Endmonat bereits überschreitet
Stunden_Ende_Monat_ueber = as.numeric(difftime(
TATZEIT_ENDE,
as.POSIXct(paste(year(TATZEIT_ENDE), month(TATZEIT_ENDE), 1, sep = "-")),
units = "hours"
)),
# Subtrahiere die Stunden des Endmonats von der Dauer, um Stunden im Anfangsmonat zu erhalten
Stunden_Anfang_Monat = pmax(Dauer - Stunden_Ende_Monat_ueber, 0), # Sicherstellen, dass keine negativen Stunden auftauchen
# Stunden im Endmonat: Die restlichen Stunden, die im Endmonat verbracht wurden
Stunden_Ende_Monat = pmax(Stunden_Ende_Monat_ueber, 0)
)
# Zähle, wie oft der Diebstahl im Anfangsmonat mehr Stunden hatte und im Endmonat mehr Stunden und anschließend jeweils die Gesamtstunden
analyse_zeiten <- fahrraddiebstahl_ueber_mehrere_monate %>%
summarise(
# Zähle, wie oft der Diebstahl im Anfangsmonat mehr Stunden hatte
Anfang_Monat_Mehr_Stunden = sum(Stunden_Anfang_Monat > Stunden_Ende_Monat, na.rm = TRUE),
# Zähle, wie oft der Diebstahl im Endmonat mehr Stunden hatte
End_Monat_Mehr_Stunden = sum(Stunden_Ende_Monat > Stunden_Anfang_Monat, na.rm = TRUE),
# Berechne die Gesamtstunden für die Fälle, in denen im Anfangsmonat mehr Stunden verbracht wurden
Gesamtstunden_Anfang_Monat = sum(Stunden_Anfang_Monat[Stunden_Anfang_Monat > Stunden_Ende_Monat], na.rm = TRUE),
# Berechne die Gesamtstunden für die Fälle, in denen im Endmonat mehr Stunden verbracht wurden
Gesamtstunden_End_Monat = sum(Stunden_Ende_Monat[Stunden_Ende_Monat > Stunden_Anfang_Monat], na.rm = TRUE)
)
# Ausgabe der Analyse als knitr-Tabelle
kable(analyse_zeiten, caption = "Analyse der Stundenverteilung bei Diebstählen über zwei Monate", format = "markdown")
| Anfang_Monat_Mehr_Stunden | End_Monat_Mehr_Stunden | Gesamtstunden_Anfang_Monat | Gesamtstunden_End_Monat |
|---|---|---|---|
| 274 | 460 | 7257 | 10333 |
Das Ergebnis zeigt, dass die Unterschiede signifikant sind. Es gibt fast doppelt so viele Stunden im anderen Monat, die zu Beginn erfasst wurden, im Vergleich zu denen, die in den folgenden Monat übergehen. Trotz dieser Verlagerung bleibt die Stundenanzahl im ursprünglichen Monat höher. Eine Tatzeitdauer von nur 3 Tagen ist daher nicht ausreichend, um diese Unterschiede angemessen zu erfassen. Die nachfolgende Analyse basiert darauf, die geeignete Tatzeitdauer zu ermitteln, um die Unterschiede präzise zu erfassen und eine aussagekräftige Auswertung zu gewährleisten.
# Filtern der Diebstähle mit Dauer <= 24 Stunden
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 24)
# Konvertiere TATZEIT_ANFANG und TATZEIT_ENDE in Jahr und Monat
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(
Jahr_Anfang = year(TATZEIT_ANFANG),
Monat_Anfang = month(TATZEIT_ANFANG, label = TRUE, abbr = TRUE),
Jahr_Ende = year(TATZEIT_ENDE),
Monat_Ende = month(TATZEIT_ENDE, label = TRUE, abbr = TRUE)
)
# Filtern nach Anfangsmonat != Endmonat und im selben Jahr
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_ueber_mehrere_monate %>%
filter(
!is.na(TATZEIT_ENDE),
Monat_Anfang != Monat_Ende,
Jahr_Anfang == Jahr_Ende
)
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_ueber_mehrere_monate %>%
mutate(
# Berechne, wie viele Stunden der Endmonat bereits überschreitet
Stunden_Ende_Monat_ueber = as.numeric(difftime(
TATZEIT_ENDE,
as.POSIXct(paste(year(TATZEIT_ENDE), month(TATZEIT_ENDE), 1, sep = "-")),
units = "hours"
)),
# Subtrahiere die Stunden des Endmonats von der Dauer, um Stunden im Anfangsmonat zu erhalten
Stunden_Anfang_Monat = pmax(Dauer - Stunden_Ende_Monat_ueber, 0), # Sicherstellen, dass keine negativen Stunden auftauchen
# Stunden im Endmonat: Die restlichen Stunden, die im Endmonat verbracht wurden
Stunden_Ende_Monat = pmax(Stunden_Ende_Monat_ueber, 0)
)
# Zähle, wie oft der Diebstahl im Anfangsmonat mehr Stunden hatte und im Endmonat mehr Stunden und anschließend jeweils die Gesamtstunden
analyse_zeiten <- fahrraddiebstahl_ueber_mehrere_monate %>%
summarise(
# Zähle, wie oft der Diebstahl im Anfangsmonat mehr Stunden hatte
Anfang_Monat_Mehr_Stunden = sum(Stunden_Anfang_Monat > Stunden_Ende_Monat, na.rm = TRUE),
# Zähle, wie oft der Diebstahl im Endmonat mehr Stunden hatte
End_Monat_Mehr_Stunden = sum(Stunden_Ende_Monat > Stunden_Anfang_Monat, na.rm = TRUE),
# Berechne die Gesamtstunden für die Fälle, in denen im Anfangsmonat mehr Stunden verbracht wurden
Gesamtstunden_Anfang_Monat = sum(Stunden_Anfang_Monat[Stunden_Anfang_Monat > Stunden_Ende_Monat], na.rm = TRUE),
# Berechne die Gesamtstunden für die Fälle, in denen im Endmonat mehr Stunden verbracht wurden
Gesamtstunden_End_Monat = sum(Stunden_Ende_Monat[Stunden_Ende_Monat > Stunden_Anfang_Monat], na.rm = TRUE)
)
# Ausgabe der Analyse als knitr-Tabelle
kable(analyse_zeiten, caption = "Analyse der Stundenverteilung bei Diebstählen über zwei Monate", format = "markdown")
| Anfang_Monat_Mehr_Stunden | End_Monat_Mehr_Stunden | Gesamtstunden_Anfang_Monat | Gesamtstunden_End_Monat |
|---|---|---|---|
| 99 | 251 | 882 | 2463 |
Bei einer Tatzeitdauer von einem Tag sind die Unterschiede ebenfalls signifikant und sogar anteilig noch ausgeprägter (Faktor 5). Dies deutet darauf hin, dass diese Zeitspanne ebenfalls nicht ausreicht, um die tatsächlichen Schwankungen adäquat abzubilden.
# Filtern der Diebstähle mit Dauer <= 24 Stunden
fahrraddiebstahl_beschränkte_dauer_df <- fahrraddiebstahl_dauer_df %>%
filter(Dauer <= 6)
# Konvertiere TATZEIT_ANFANG und TATZEIT_ENDE in Jahr und Monat
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_beschränkte_dauer_df %>%
mutate(
Jahr_Anfang = year(TATZEIT_ANFANG),
Monat_Anfang = month(TATZEIT_ANFANG, label = TRUE, abbr = TRUE),
Jahr_Ende = year(TATZEIT_ENDE),
Monat_Ende = month(TATZEIT_ENDE, label = TRUE, abbr = TRUE)
)
# Filtern nach Anfangsmonat != Endmonat und im selben Jahr
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_ueber_mehrere_monate %>%
filter(
!is.na(TATZEIT_ENDE),
Monat_Anfang != Monat_Ende,
Jahr_Anfang == Jahr_Ende
)
fahrraddiebstahl_ueber_mehrere_monate <- fahrraddiebstahl_ueber_mehrere_monate %>%
mutate(
# Berechne, wie viele Stunden der Endmonat bereits überschreitet
Stunden_Ende_Monat_ueber = as.numeric(difftime(
TATZEIT_ENDE,
as.POSIXct(paste(year(TATZEIT_ENDE), month(TATZEIT_ENDE), 1, sep = "-")),
units = "hours"
)),
# Subtrahiere die Stunden des Endmonats von der Dauer, um Stunden im Anfangsmonat zu erhalten
Stunden_Anfang_Monat = pmax(Dauer - Stunden_Ende_Monat_ueber, 0), # Sicherstellen, dass keine negativen Stunden auftauchen
# Stunden im Endmonat: Die restlichen Stunden, die im Endmonat verbracht wurden
Stunden_Ende_Monat = pmax(Stunden_Ende_Monat_ueber, 0)
)
# Zähle, wie oft der Diebstahl im Anfangsmonat mehr Stunden hatte und im Endmonat mehr Stunden und anschließend jeweils die Gesamtstunden
analyse_zeiten <- fahrraddiebstahl_ueber_mehrere_monate %>%
summarise(
# Zähle, wie oft der Diebstahl im Anfangsmonat mehr Stunden hatte
Anfang_Monat_Mehr_Stunden = sum(Stunden_Anfang_Monat > Stunden_Ende_Monat, na.rm = TRUE),
# Zähle, wie oft der Diebstahl im Endmonat mehr Stunden hatte
End_Monat_Mehr_Stunden = sum(Stunden_Ende_Monat > Stunden_Anfang_Monat, na.rm = TRUE),
# Berechne die Gesamtstunden für die Fälle, in denen im Anfangsmonat mehr Stunden verbracht wurden
Gesamtstunden_Anfang_Monat = sum(Stunden_Anfang_Monat[Stunden_Anfang_Monat > Stunden_Ende_Monat], na.rm = TRUE),
# Berechne die Gesamtstunden für die Fälle, in denen im Endmonat mehr Stunden verbracht wurden
Gesamtstunden_End_Monat = sum(Stunden_Ende_Monat[Stunden_Ende_Monat > Stunden_Anfang_Monat], na.rm = TRUE)
)
# Ausgabe der Analyse als knitr-Tabelle
kable(analyse_zeiten, caption = "Analyse der Stundenverteilung bei Diebstählen über zwei Monate", format = "markdown")
| Anfang_Monat_Mehr_Stunden | End_Monat_Mehr_Stunden | Gesamtstunden_Anfang_Monat | Gesamtstunden_End_Monat |
|---|---|---|---|
| 16 | 2 | 55 | 7 |
Bei einer Tatzeitdauer von ≤ 6 Stunden sind die Unterschiede ebenfalls präsent und, anteilig betrachtet, sogar fast um den Faktor 4 ausgeprägter. Dies deutet darauf hin, dass eine so kurze Zeitspanne möglicherweise nicht ausreicht, um die tatsächlichen Schwankungen korrekt abzubilden. Da die Einteilung in noch kleinere Tatzeiträume den Datensatz erheblich verkleinern würde, erscheint ein Tatzeitraum von ≤ 73 Stunden als die beste Wahl, um eine genauere und aussagekräftigere Analyse zu ermöglichen. Somit ist das oben dargestellte Balkendiagramm mit der Tatzeitdauereinteilung von ≤ 73 Stunden für den Datensatz am besten geeignet, da es die Verteilung der präferierten Tatzeiten zwar mit einer kleinen Verzerrung, aber dennoch, wie die Analyse zeigte, am besten abbildet.
In diesem Unterkapitel wird abschließend zur Analyse der bevorzugten Tage und Monate die durchschnittliche Anzahl der Diebstähle pro Monat dargestellt. Da der Datensatz aus zwei Jahren besteht, werden die Diebstahlzahlen durch zwei geteilt. Eine Ausnahme bilden die Monate Oktober, November und Dezember, da für das Jahr 2024 nur Daten bis zum 18. Oktober vorliegen. Diese Erkenntnisse wurden durch die Betrachtung des Datensatzes in der Anwendung Excel gewonnen.
# Konvertiere TATZEIT_ANFANG_DATUM zu Datum und extrahiere den Monat
fahrraddiebstahl_datensatz_df <- fahrraddiebstahl_datensatz_df %>%
mutate(
TATZEIT_DATUM_ANZAHL = as.Date(TATZEIT_ANFANG_DATUM, format = "%d.%m.%Y") # Konvertiere TATZEIT_ANFANG_DATUM zu Datum
)
# Monatsspezifische Anpassungen der Anzahl
monat_anzahl <- fahrraddiebstahl_datensatz_df %>%
filter(!is.na(TATZEIT_DATUM_ANZAHL)) %>%
mutate(Monat = month(TATZEIT_DATUM_ANZAHL, label = TRUE, abbr = TRUE)) %>% # Extrahiere Monat
group_by(Monat) %>%
summarise(Anzahl = n(), .groups = "drop")
# Halbiere die Anzahl der Fälle für Januar bis Oktober, da die Anzahl aus zwei Jahren stammt
monat_anzahl <- monat_anzahl %>%
mutate(Anzahl = case_when(
Monat %in% c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct") ~
ifelse(Monat == "Oct", Anzahl / (1 + 18 / 31), Anzahl / 2), # Spezielle Berechnung für Oktober
TRUE ~ Anzahl
))
# Plot nur für Monate
ggplot(monat_anzahl, aes(x = Monat, y = Anzahl, fill = Monat)) +
geom_bar(stat = "identity") +
labs(
title = "Durchschnittliche Anzahl an Fällen von Fahrraddiebstählen je Monat",
x = "Monat",
y = "Anzahl der Fälle",
fill = "Monat"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Optional: für bessere Lesbarkeit der Monatsnamen
Das Diagramm zeigt die durchschnittliche Anzahl von Fahrraddiebstählen pro Monat. In Form eines Balkendiagramms veranschaulicht die Höhe jedes Balkens die durchschnittliche Diebstahlzahl für einen bestimmten Monat. Die Balken sind farblich nach Monaten unterteilt, wodurch saisonale Schwankungen auf einen Blick erkennbar sind. Auch hier wurde der gesamte Datensatz verwendet, da die zugrunde liegende Begründung für diese Analyse ebenso gilt. Es handelt sich um die gleichen analysierten Daten, lediglich aufbereitet durch die Berechnung von Durchschnittswerten.
Saisonalität: Auch hier sind deutliche Schwankungen sichtbar. Höchstwerte: Der Mai weist die höchste Anzahl an Fahrraddiebstählen auf. Tiefstwerte: Die geringsten Diebstahlszahlen treten in den Wintermonaten (Dezember, Januar, Februar) auf.
Abschließend lässt sich zum Kapitel der präferierten Zeiten festhalten, dass die meisten Fahrraddiebstähle am Nachmittag stattfinden. Zudem ist die Anzahl der Diebstähle an Werktagen deutlich höher. In der warmen Saison steigen die Diebstahlzahlen erheblich an.